Você está na página 1de 1658

Incisive Enterprise Specman Elite Testbench

Specman e Language Reference


Product Version 15.1
July 2015

1998-2015 Cadence Design Systems, Inc. All rights reserved worldwide.


Printed in the United States of America.
Cadence Design Systems, Inc. (Cadence), 2655 Seely Ave., San Jose, CA 95134, USA.
This product contains third party software. Please refer to <install_dir>/doc/thirdpartyinfo/SPMNthirdpartyinfo.txt to review
copyright & licensing terms.
Trademarks: Trademarks and service marks of Cadence Design Systems, Inc. contained in this document are attributed to
Cadence with the appropriate symbol. For queries regarding Cadences trademarks, contact the corporate legal department at
the address shown above or call 800.862.4522. All other trademarks are the property of their respective holders.
Open SystemC, Open SystemC Initiative, OSCI, SystemC, and SystemC Initiative are trademarks or registered trademarks of
Open SystemC Initiative, Inc. in the United States and other countries and are used with permission.
Restricted Permission: This publication is protected by copyright law and international treaties and contains trade secrets
and proprietary information owned by Cadence. Unauthorized reproduction or distribution of this publication, or any portion
of it, may result in civil and criminal penalties. Except as specified in this permission statement, this publication may not be
copied, reproduced, modified, published, uploaded, posted, transmitted, or distributed in any way, without prior written
permission from Cadence. Unless otherwise agreed to by Cadence in writing, this statement grants Cadence customers
permission to print one (1) hard copy of this publication subject to the following conditions:
1. The publication may be used only in accordance with a written agreement between Cadence and its customer;
2. The publication may not be modified in any way;
3. Any authorized copy of the publication or portion thereof must include all original copyright, trademark, and other
proprietary notices and this permission statement;
4. The information contained in this document cannot be used in the development of like products or software, whether
for internal or external use, and shall not be used for the benefit of any other party, whether or not for consideration
Disclaimer: Information in this publication is subject to change without notice and does not represent a commitment on the
part of Cadence. Except as may be explicitly set forth in such agreement, Cadence does not make, and expressly disclaims, any
representations or warranties as to the completeness, accuracy or usefulness of the information contained in this document.
Cadence does not warrant that use of such information will not infringe any third party rights, nor does Cadence assume any
liability for damages or costs of any kind that may result from use of such information.
Restricted Rights: Use, duplication, or disclosure by the Government is subject to restrictions as set forth in FAR52.22714 and DFAR252.227-7013 et seq. or its successor.

Contents
1

e Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.1

1.2

Lexical Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34


1.1.1
File Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34
1.1.2
Code Segments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34
1.1.3
Comments and White Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35
1.1.4
Literals and Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35
1.1.4.1 Unsized Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36
1.1.4.2 Sized Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37
1.1.4.3 MVL Literals and the mvl Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37
1.1.4.4 Predefined Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39
1.1.4.5 Literal String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40
1.1.4.6 Literal Character . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41
1.1.5
Names, Keywords, and Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41
1.1.5.1 Legal e Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41
1.1.5.2 Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42
Syntactic Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42
1.2.1
Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43
1.2.2
Struct Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
1.2.3
Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
1.2.3.1 Creating or Modifying Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47
1.2.3.2 Executing Actions Conditionally . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
1.2.3.3 Executing Actions Iteratively . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
1.2.3.4 Controlling Program Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
1.2.3.5 Invoking Methods and Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
1.2.3.6 Performing Time-Consuming Actions . . . . . . . . . . . . . . . . . . . . . . . . .50
1.2.3.7 Generating Data Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
1.2.3.8 Detecting and Handling Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
1.2.3.9 Printing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .52
1.2.4
Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .52

Specman e Language Reference


1999-2015

Product Version 15.1


All Rights Reserved.

1.3

1.4
1.5
1.6

1.7

1.8

1.9

1.2.4.1 Avoiding problematic long expression parsing . . . . . . . . . . . . . . . . . .53


Struct Hierarchy and Name Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .54
1.3.1
Struct Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .54
1.3.1.1 Global Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .55
1.3.1.2 Sys Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .56
1.3.1.3 Files Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .56
1.3.1.4 Covers Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .56
1.3.1.5 Packing Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .57
1.3.1.6 Scheduler Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .57
1.3.1.7 Session Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .57
1.3.1.8 Simulator Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .58
1.3.2
Referencing e Entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .58
1.3.2.1 Structs and Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .59
1.3.2.2 Method and Routine Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .60
1.3.2.3 Enumerated Type Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .61
1.3.3
Implicit Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62
1.3.3.1 it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62
1.3.3.2 me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .63
1.3.3.3 result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .64
1.3.3.4 index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .64
1.3.4
Name Resolution Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .65
1.3.4.1 Names that Include a Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .65
1.3.4.2 Names that Do Not Include a Path . . . . . . . . . . . . . . . . . . . . . . . . . . . .66
Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .68
Evaluation Order of Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .69
Bitwise Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .70
1.6.1
~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .70
1.6.2
& | ^ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .72
1.6.3
>> << . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .74
Boolean Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .76
1.7.1
! (not) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .76
1.7.2
&& (and) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .78
1.7.3
|| (or) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .79
1.7.4
=> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .80
1.7.5
now . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .81
Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .84
1.8.1
Unary + - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .84
1.8.2
+ - * / % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .85
Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .87
1.9.1
< <= > >= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .87

Specman e Language Reference


1999-2015

Product Version 15.1


All Rights Reserved.

1.10

1.11

1.12

1.13
1.14

1.9.2
== != . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89
1.9.3
=== !== . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91
1.9.4
~ !~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .94
1.9.5
in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96
String Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .99
1.10.1 Native Specman String Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .99
1.10.2 AWK-Style String Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
Extraction and Concatenation Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .103
1.11.1 [ ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .103
1.11.2 [ : ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105
1.11.3 [ .. ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .110
1.11.4 {... ; ...} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .113
1.11.5 %{... , ...} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .115
Scalar Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .118
1.12.1 [ range,...] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
1.12.2 (bits | bytes : width-exp) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .120
Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121
1.13.1 list-method() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121
Special-Purpose Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123
1.14.1 is [not] a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123
1.14.2 new . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .125
1.14.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .128
1.14.4 ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
1.14.5 ? : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
1.14.6 evaluate { ... } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .133

Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137


2.1

e Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137


2.1.1
Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .138
2.1.1.1 Predefined Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .139
2.1.2
Scalar Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .140
2.1.2.1 Scalar Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .140
2.1.2.2 Named Scalar Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
2.1.2.3 Infinite (Unbounded or Long) Integers . . . . . . . . . . . . . . . . . . . . . . .141
2.1.3
The set Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
2.1.3.1 Set Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
2.1.3.2 Restrictions on Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
2.1.3.3 Set Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144

Specman e Language Reference


1999-2015

Product Version 15.1


All Rights Reserved.

2.2
2.3
2.4

2.1.3.4 String Representation of set Type . . . . . . . . . . . . . . . . . . . . . . . . . . .145


2.1.3.5 Responding to the Warning WARN_INT_UINT_SET_SEMANTICS .
145
2.1.4
Enumerated Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .145
2.1.4.1 Integers Associated with the Enumerated Constants . . . . . . . . . . . . .146
2.1.4.2 Assigning Values to the Enumerated Constants . . . . . . . . . . . . . . . .147
2.1.4.3 Naming an Enumerated Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .147
2.1.4.4 Extending and Sizing Enumerated Types . . . . . . . . . . . . . . . . . . . . .147
2.1.4.5 Casting of Enumerated Types in Comparisons . . . . . . . . . . . . . . . . .148
2.1.5
Struct Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149
2.1.6
Struct Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .150
2.1.6.1 Referring to a Struct Subtype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .151
2.1.6.2 Using extend, when, and like with Struct Subtypes . . . . . . . . . . . . .152
2.1.6.3 Referring To Conditional Fields in when Constructs . . . . . . . . . . . .153
2.1.7
List Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155
2.1.7.1 One-Dimensional (Regular) Lists . . . . . . . . . . . . . . . . . . . . . . . . . . .156
2.1.7.2 Multi-Dimensional Lists (Lists of Lists) . . . . . . . . . . . . . . . . . . . . . .156
2.1.7.3 Keyed Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .157
2.1.8
The string Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158
2.1.9
The real Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158
2.1.9.1 Limitations for Type real . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159
2.1.9.2 Real Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160
2.1.9.3 Predefined Real Constants for Analog Mixed-Signal (AMS) . . . . . .161
2.1.9.4 Conversion Between Real and Numeric Types . . . . . . . . . . . . . . . . .162
2.1.9.5 Conversions Between Real and Non-Numeric Types . . . . . . . . . . . .162
2.1.9.6 Packing Values for real Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .163
2.1.9.7 Printing Real Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .163
2.1.10 The external_pointer Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164
2.1.11 The untyped Pseudo Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164
2.1.12 unsafe() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164
Memory Requirements for Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .165
Untyped Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .166
Assignment Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .169
2.4.1
What Is an Assignment? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .169
2.4.2
Assignments That Create Identical References . . . . . . . . . . . . . . . . . . . . . . . .170
2.4.3
Assignment of Numeric Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
2.4.4
Assignment of Boolean Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .172
2.4.5
Assignment of Enumerated Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .172
2.4.6
Assignment of Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173
2.4.7
Assignment of Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174

Specman e Language Reference


1999-2015

Product Version 15.1


All Rights Reserved.

2.4.8
Assignment of Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
2.4.9
Assignment of Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
2.5 Precision Rules for Numeric Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176
2.5.1
Determining the Context of an Expression . . . . . . . . . . . . . . . . . . . . . . . . . . .177
2.5.2
Deciding Precision and Performing Data Conversion and Sign Extension . . .178
2.5.3
Example Application of Precision Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . .179
2.6 Automatic Type Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .180
2.7 Defining and Extending Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .182
2.7.1
type enumerated scalar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .183
2.7.2
type scalar subtype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .185
2.7.3
type sized scalar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .187
2.7.4
extend type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .189
2.8 Referring to Types in Generic Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .190
2.8.1
typeof() / typeof_item() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .191
2.9 Converting from One Data Type to Another . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .194
2.9.1
as_a() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .194
2.9.1.1 as_a Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .195
2.9.2
Type Conversion Between Scalars and Lists of Scalars . . . . . . . . . . . . . . . . .202
2.9.3
Type Conversion Between Strings and Scalars or Lists of Scalars . . . . . . . . .204
2.9.4
Type Conversion Between Structs, Struct Subtypes, and Lists of Structs . . . .206
2.9.5
Type Conversion Between Simple Lists and Keyed Lists . . . . . . . . . . . . . . . .207
2.9.6
Type Conversion Between Multi-Dimensional Lists . . . . . . . . . . . . . . . . . . . .208
2.9.7
Type Conversion Between Lists of Numeric and Set . . . . . . . . . . . . . . . . . . .208
2.10 Accessing All Values of a Scalar Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209
2.10.1 all_values() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209
2.10.2 set_of_values(type) / full_set_of_values(type) . . . . . . . . . . . . . . . . . . . . . . . .211

Structs, Fields, and Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215


3.1
3.2
3.3
3.4
3.5

Structs Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .216


Defining Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .216
3.2.1
struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .216
Extending Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .219
3.3.1
extend type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .219
Extending Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .222
Defining Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .225
3.5.1
field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .225
3.5.2
Constant Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .228

Specman e Language Reference


1999-2015

Product Version 15.1


All Rights Reserved.

3.5.2.1 Initializing const Fields for Structs . . . . . . . . . . . . . . . . . . . . . . . . . .230


3.5.2.2 Initializing const Unit Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .230
3.5.2.3 Notes about Initialization of const Fields . . . . . . . . . . . . . . . . . . . . .231
3.5.2.4 Restrictions for const Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .231
3.6 Defining List Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .231
3.6.1
list of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .231
3.6.2
list(key) of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .235
3.7 Creating Subtypes with When . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .241
3.7.1
when . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .241
3.8 Extending When Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .244
3.8.1
Coverage and When Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .245
3.8.2
Extending Methods in When Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .246
3.8.3
When Subtypes and expect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .248
3.9 Defining Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .248
3.9.1
attribute field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .248
3.10 Comparison of When and Like Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .252
3.10.1 Summary of When versus Like . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253
3.10.2 A Simple Example of When Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253
3.10.3 A Simple Example of Like Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .255
3.10.4 Advantages of Using When Inheritance for Modeling . . . . . . . . . . . . . . . . . .256
3.10.5 Advantages of Using Like Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .259
3.10.6 Restrictions on Like Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .261
3.10.6.1 Restrictions Due to Inherent Differences . . . . . . . . . . . . . . . . . . . . . .261
3.10.6.2 Restrictions Due to Implementation . . . . . . . . . . . . . . . . . . . . . . . . .261
3.10.6.3 Examples of Like Inheritance Restrictions . . . . . . . . . . . . . . . . . . . .262
3.10.7 A When Inheritance Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .263

Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
4.1

4.2

Units Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .265


4.1.1
Units vs. Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .267
4.1.2
HDL Paths and Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .268
4.1.3
Unit Hierarchical References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .269
4.1.4
Methodology Recommendations and Limitations . . . . . . . . . . . . . . . . . . . . . .269
Defining Units and Fields of Type Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .270
4.2.1
unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .271
4.2.2
field: unit-type is instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .275
4.2.3
field: unit-type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .277
4.2.4
field: list of unit instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .279

Specman e Language Reference


1999-2015

Product Version 15.1


All Rights Reserved.

4.3

4.4

4.5

4.2.5
field: list of unit-type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .280
Predefined Attributes and Methods for Any Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .282
4.3.1
agent() Unit Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .283
4.3.2
agent_code() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .288
4.3.3
analog_agent_code() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .289
4.3.4
analog_code() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .290
4.3.5
e_path() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .291
4.3.6
full_external_uvm_path() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .293
4.3.7
full_hdl_path() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .294
4.3.8
get_native_path_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .296
4.3.9
get_parent_unit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .297
4.3.10 get_ports() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .298
4.3.11 get_ports_recursively() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .299
4.3.12 hdl_path() Unit Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .300
4.3.13 pack_options() Unit Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .303
4.3.14 per_inst_cover() Unit Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .303
4.3.15 short_name_path(), short_name(), and short_name_style() . . . . . . . . . . . . . . .305
Unit-Related Predefined Methods for Any Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . .307
4.4.1
get_unit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .307
4.4.2
get_all_units() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .310
4.4.3
get_enclosing_unit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .312
4.4.4
try_enclosing_unit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .315
4.4.5
set_unit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .316
Unit-Related Predefined Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .317
4.5.1
set_config_max() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .317

Template Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321


5.1
5.2
5.3

5.4

5.5

Defining a Template Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .321


Extending a Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .326
Instantiating a Template Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .328
5.3.1
Template Subtype Instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .329
5.3.2
Forward References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .330
Template Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .330
5.4.1
Template Definition Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .330
5.4.2
Template Instantiation Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .331
5.4.3
Run-Time Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .332
Template Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .332

Specman e Language Reference


1999-2015

Product Version 15.1


All Rights Reserved.

5.6

Templates Versus Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .332

e Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
6.1

6.2

6.3

6.4

Simple Port Declarations, References, and Access Operators . . . . . . . . . . . . . . . . . . . .338


6.1.1
simple_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .338
6.1.2
any_simple_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .340
6.1.3
simple_port$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .342
6.1.4
simple_port$[ : ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .343
6.1.5
force port$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .348
6.1.6
force port$[ : ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .350
6.1.7
release port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .352
Simple Port MVL Access Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .353
6.2.1
put_mvl() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .354
6.2.2
get_mvl() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .355
6.2.3
put_mvl_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .356
6.2.4
fill_mvl_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .357
6.2.5
get_mvl_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .360
6.2.6
put_mvl_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .362
6.2.7
get_mvl_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
6.2.8
get_mvl4() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .364
6.2.9
fill_mvl4_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .366
6.2.10 get_mvl4_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .367
6.2.11 get_mvl4_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .369
6.2.12 put_mvl_to_bit_slice() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .370
6.2.13 force_mvl() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .372
6.2.14 force_mvl_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .373
6.2.15 force_mvl_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .375
6.2.16 force_mvl_to_bit_slice() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .376
6.2.17 has_mvl_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .378
6.2.18 has_x() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .379
6.2.19 has_z() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .380
6.2.20 has_unknown() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .381
Simple Port Default Value Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .382
6.3.1
set_default_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .382
6.3.2
set_default_mvl_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .384
Global MVL Conversion Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .386
6.4.1
string_to_mvl() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .387

Specman e Language Reference


1999-2015

10

Product Version 15.1


All Rights Reserved.

6.5

6.6

6.7
6.8

6.9

6.4.2
mvl_to_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .388
6.4.3
mvl_to_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .389
6.4.4
int_to_mvl() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .390
6.4.5
mvl_to_bits() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .391
6.4.6
bits_to_mvl() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .392
6.4.7
mvl_to_mvl4() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .393
6.4.8
convert_mvl_list_to_mvl4_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .395
6.4.9
mvl_list_to_mvl4_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .396
6.4.10 string_to_mvl4() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .397
Simple Indexed Port Declaration and Access Operator . . . . . . . . . . . . . . . . . . . . . . . . .398
6.5.1
simple_port(index-method-type) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .398
6.5.2
index()$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .402
Event Port Declarations, References, and Access Operator . . . . . . . . . . . . . . . . . . . . . .404
6.6.1
event_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .405
6.6.2
any_event_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .408
6.6.3
event_port$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .410
API for Controlling Event Port Sensitivity at Run Time . . . . . . . . . . . . . . . . . . . . . . . .412
6.7.1
event-port.disable() / event-port.enable() . . . . . . . . . . . . . . . . . . . . . . . . . . . . .412
Method Port Declarations, References, and Access Operator . . . . . . . . . . . . . . . . . . . .414
6.8.1
method_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .414
6.8.2
method_type method-type-name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .415
6.8.3
any_method_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .417
6.8.4
method_port$() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .418
Buffer Port Declarations, References, and Access Methods . . . . . . . . . . . . . . . . . . . . .420
6.9.1
buffer_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .420
6.9.2
any_buffer_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .422
6.9.3
get() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .424
6.9.4
put() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .425
6.9.5
nb_get() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .426
6.9.6
nb_put() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .428
6.9.7
nb_insert() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .429
6.9.8
nb_remove() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .430
6.9.9
nb_peek() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .431
6.9.10 top() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .432
6.9.11 nb_top() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .433
6.9.12 is_empty() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .435
6.9.13 is_full() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .436

Specman e Language Reference


1999-2015

11

Product Version 15.1


All Rights Reserved.

6.10

6.11

6.12

6.13

6.14

6.9.14 clear_buffer() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .437


6.9.15 number_of_elements() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .438
6.9.16 number_of_free_elements() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .439
e Port Binding Declarations and Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .440
6.10.1 bind() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .441
6.10.2 connect_pointers() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .445
6.10.3 connect_ports() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .446
6.10.4 check_generation() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .448
6.10.5 do_bind() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .449
6.10.6 do_bind_unit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .451
6.10.7 connect() for e2e Method Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .454
6.10.8 remap_hdl_path() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .457
6.10.9 disconnect() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .459
6.10.10 disconnect_bound_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .460
6.10.11 get_bound_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .461
6.10.12 is_connected() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .463
6.10.13 The connect_pointers() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .464
6.10.14 The connect_ports() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .467
6.10.15 The check_generation() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .469
Port-Related Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .470
6.11.1 get_hdl_size() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .470
6.11.2 simulator.get_hdl_path_size() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .472
6.11.3 simulator.path_exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .473
e TLM Interface Port Declaration and Access Operator . . . . . . . . . . . . . . . . . . . . . . . .474
6.12.1 interface_port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .474
6.12.2 tlm-interface-port$.tlm-method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .477
e TLM Interface Port Binding Declarations and Methods . . . . . . . . . . . . . . . . . . . . . . .479
6.13.1 connect() for e TLM Interface Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .479
6.13.2 remap_external_uvm_path() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .483
6.13.3 Methods for Getting Bound Sets for e TLM Interface Ports . . . . . . . . . . . . . .484
e TLM 2.0 Socket Declaration and Predefined Methods . . . . . . . . . . . . . . . . . . . . . . . .486
6.14.1 tlm_initiator_socket / tlm_target_socket . . . . . . . . . . . . . . . . . . . . . . . . . . . . .486
6.14.2 b_transport() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .489
6.14.3 nb_transport_fw() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .493
6.14.4 nb_transport_bw() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .497
6.14.5 transport_dbg() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .500
6.14.6 set_bus_width() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .502

Specman e Language Reference


1999-2015

12

Product Version 15.1


All Rights Reserved.

6.14.7 get_bus_width() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .503


6.15 e TLM 2.0 Predefined Structs and Enumerated Data Types . . . . . . . . . . . . . . . . . . . . .504
6.15.1 tlm_command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .504
6.15.2 tlm_endianness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .505
6.15.3 tlm_extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .506
6.15.4 tlm_generic_payload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .507
6.15.5 tlm_phase_enum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .511
6.15.6 tlm_response_status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .512
6.15.7 tlm_sync_enum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .514
6.16 e TLM 2.0 Socket Binding Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .515
6.16.1 connect() for e TLM 2.0 Sockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .515

Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
7.1

7.2

Creating and Modifying e Variables . . . . . . . . . . . . . . . . . . . . . . . . 549


8.1
8.2
8.3
8.4
8.5

Defining and Extending Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .517


7.1.1
method is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .518
7.1.2
method @event is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .521
7.1.3
method [@event] is also | first | only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .525
7.1.4
method [@event] is undefined | empty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .532
Invoking Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .535
7.2.1
tcm() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .535
7.2.2
start tcm() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .537
7.2.3
method() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .540
7.2.4
compute method() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .542
7.2.5
return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .543

About e Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .549


var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .550
= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .552
op= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .554
<= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .557

Control Flow Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561


9.1

Conditional Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .561


9.1.1
if then else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .561
9.1.2
case labeled-case-item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .563

Specman e Language Reference


1999-2015

13

Product Version 15.1


All Rights Reserved.

9.2

9.3

9.4

10

9.1.3
case bool-case-item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .566
Iterative Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .568
9.2.1
while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .568
9.2.2
repeat until . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .570
9.2.3
for each in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .572
9.2.4
for each in set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .575
9.2.5
for from to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .577
9.2.6
for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .579
File Iteration Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .581
9.3.1
for each line in file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .581
9.3.2
for each file matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .582
Actions for Controlling the Program Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .584
9.4.1
break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .584
9.4.2
continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .585

Checks and Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587


10.1 Handling DUT Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .587
10.1.1 check that . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .588
10.1.2 dut_error() and dut_errorf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .591
10.1.3 dut_error_struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .594
10.1.4 set_check() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .599
10.1.5 set_check_by_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .602
10.2 Handling User Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .606
10.2.1 warning() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .606
10.2.2 error() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .607
10.2.3 fatal() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .609
10.2.4 try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .612
10.3 Handling Programming Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .614
10.3.1 assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .614

11

Generation Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617


11.1 Defining Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .617
11.1.1 constraint-def and bool-constraint-def . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .618
11.1.1.1 constraint-def . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .618
11.1.1.2 bool-constraint-def . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .619
11.1.2 keep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .620
11.1.3 Compound Constraint Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .623

Specman e Language Reference


1999-2015

14

Product Version 15.1


All Rights Reserved.

11.1.4 for each . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .625


11.1.5 type ...is a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .629
11.1.6 struct-list.is_all_iterations() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .635
11.1.7 soft... select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .637
11.1.8 gen-item.reset_soft() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .644
11.1.9 name is [only] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .646
11.1.10 read_only() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .649
11.1.11 Unidirectional Constraint Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .650
11.2 Initiating Generation On the Fly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .652
11.2.1 gen...keeping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .653
11.3 Using Procedural Code During Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .656
11.3.1 pre_generate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .656
11.3.2 post_generate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .658
11.4 Macro for Choosing the Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .659
11.4.1 IF_USING_GEN(name) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .659

12

Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661
12.1 event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .662
12.2 emit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .666

13

Temporal Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669


13.1
13.2
13.3
13.4
13.5
13.6
13.7
13.8
13.9
13.10
13.11
13.12
13.13
13.14
13.15
13.16

Precedence of Temporal Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .670


not . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .670
fail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .672
and . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .674
or . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .676
{ exp ; exp } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .678
eventually . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .680
[ exp ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .681
[ exp..exp ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .683
~[ exp..exp ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .685
=> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .687
detach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .689
delay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .691
@ unary event operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .693
@ sampling operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .694
cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .696

Specman e Language Reference


1999-2015

15

Product Version 15.1


All Rights Reserved.

13.17
13.18
13.19
13.20

14

true(exp) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .697
change(exp), fall(exp), rise(exp) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .699
consume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .704
exec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .707

Temporal Struct and Unit Members . . . . . . . . . . . . . . . . . . . . . . . . 713


14.1 on event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .713
14.2 on event-port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .716
14.3 expect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .717

15

Time-Consuming Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725


15.1 Synchronization Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .725
15.1.1 sync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .725
15.1.2 wait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .728
15.2 Concurrency Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .730
15.2.1 all of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .730
15.2.2 first of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .732

16

Coverage Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735


16.1 Defining Coverage Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .735
16.1.1 cover . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .735
16.2 Defining Basic Coverage Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .745
16.2.1 item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .746
16.3 Defining Cross Coverage Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .769
16.3.1 cross . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .770
16.4 Defining Transition Coverage Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .785
16.4.1 transition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .785
16.5 Extending Coverage Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .798
16.5.1 cover ... using also ... is also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .798
16.6 Extending Coverage Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .805
16.6.1 Extending Simple Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .805
16.6.1.1 item ... using also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .805
16.6.2 Extending Cross and Transition Coverage Items . . . . . . . . . . . . . . . . . . . . . . .809
16.6.2.1 (item ... using also) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .809
16.7 Collecting check/expect Results for Your Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .813
16.7.1 Item Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .813
16.7.2 Counters for checks/expects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .814

Specman e Language Reference


1999-2015

16

Product Version 15.1


All Rights Reserved.

16.7.3 Model for check that Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .815


16.7.4 Model for expect Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .816
16.8 Coverage API Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .818
16.8.1 scan_cover() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .818
16.8.2 start_group() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .820
16.8.3 start_instance() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .821
16.8.4 start_item() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .822
16.8.5 scan_bucket() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .823
16.8.6 end_item() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .824
16.8.7 end_instance() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .825
16.8.8 end_group() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .827
16.8.9 covers.sample_cg() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .828

17

Simulation-Related Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 833


17.1 Verilog and VHDL Stubs Files and Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .833
17.2 Verilog Statements or Unit Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .834
17.2.1 verilog code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .835
17.2.2 verilog function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .837
17.2.3 verilog import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .840
17.2.4 verilog task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .844
17.2.5 verilog time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .847
17.2.6 verilog variable reg | wire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .849
17.2.7 verilog variable memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .858
17.3 VHDL Statements and Unit Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .860
17.3.1 vhdl object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .861
17.3.2 vhdl code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .863
17.3.3 vhdl driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .865
17.3.4 vhdl function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .872
17.3.5 vhdl procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .876
17.3.6 vhdl time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .885
17.4 Simulation-Related Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .886
17.4.1 force . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .886
17.4.2 release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .892
17.5 Simulation-Related Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .897
17.5.1 'HDL-pathname' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .897
17.5.2 specman deferred . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .899
17.6 Simulation-Related Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .900

Specman e Language Reference


1999-2015

17

Product Version 15.1


All Rights Reserved.

17.6.1
17.6.2
17.6.3

18

simulator_command() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .900
$sn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .901
stop_run() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .902

Sequence Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905


18.1 The sequence Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .905
18.1.1 sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .905
18.2 <sequence-name>_kind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .908
18.3 any_sequence_item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .909
18.3.1 any_sequence_item.is_relevant() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .910
18.4 any_sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .911
18.4.1 any_sequence.grab() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .914
18.4.2 any_sequence.is_blocked() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .915
18.4.3 any_sequence.start_sequence() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .916
18.4.4 any_sequence.stop() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .917
18.4.5 any_sequence.ungrab() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .917
18.5 any_sequence_driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .918
18.5.1 any_sequence_driver.is_grabbed() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .924
18.5.2 any_sequence_driver.current_grabber() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .925
18.5.3 any_sequence_driver.last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .925
18.5.4 any_sequence_driver.branch_terminated() . . . . . . . . . . . . . . . . . . . . . . . . . . .927
18.5.5 any_sequence_driver.has_do_available() . . . . . . . . . . . . . . . . . . . . . . . . . . . .927
18.5.6 any_sequence_driver.wait_for_grant() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .928
18.5.7 any_sequence_driver.deliver_item() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .929
18.5.8 any_sequence_driver.execute_item() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .930
18.5.9 any_sequence_driver.queue_item() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .930
18.5.10 any_sequence_driver.wait_for_item_done() . . . . . . . . . . . . . . . . . . . . . . . . . .931
18.5.11 any_sequence_driver.wait_for_next_grant() . . . . . . . . . . . . . . . . . . . . . . . . . .932
18.5.12 any_sequence_driver.abort_do_request() . . . . . . . . . . . . . . . . . . . . . . . . . . . .933
18.6 Sequence Item do Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .933
18.6.1 do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .933
18.6.2 do_and_grab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .936
18.7 Pseudo-Routines for Tree Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .937
18.7.1 in_sequence() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .938
18.7.2 in_unit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .939

Specman e Language Reference


1999-2015

18

Product Version 15.1


All Rights Reserved.

19

Messaging Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 941


19.1 Actions for Defining Structured Debug Messages (SDMs) . . . . . . . . . . . . . . . . . . . . . .941
19.1.1 msg_started() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .942
19.1.2 msg_ended() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .944
19.1.3 msg_transformed() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .948
19.1.4 msg_changed() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .950
19.1.5 msg_info() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .953
19.2 Actions for Defining Regular Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .955
19.2.1 message() and messagef() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .956
19.3 Predefined Types Related To Messaging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .958
19.3.1 message_tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .959
19.3.2 message_manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .959
19.3.3 message_format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .960
19.3.4 message_action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .961
19.3.5 sdm_handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .963
19.4 Methods for Modifying Message Settings (via message_manager) . . . . . . . . . . . . . . . .966
19.4.1 Methods for Modifying Message Selection . . . . . . . . . . . . . . . . . . . . . . . . . . .966
19.4.1.1 set_screen_messages | set_screen_messages_off . . . . . . . . . . . . . . .966
19.4.1.2 set_transaction_messages | set_transaction_messages_off . . . . . . . .969
19.4.1.3 set_file_messages | set_file_messages_off . . . . . . . . . . . . . . . . . . . .971
19.4.2 Method for modifying message characteristics . . . . . . . . . . . . . . . . . . . . . . . .973
19.4.2.1 set_message_format() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .974
19.4.2.2 set_message_style() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .975
19.4.2.3 set_flush_frequency() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .977
19.5 Method for User-Defined Message Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .978
19.5.1 create_formatted_message() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .979
19.6 recording_config API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .982
19.6.1 recording_config Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .982
19.6.1.1 register_all_field_attributes() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .983
19.6.1.2 register_callback_attribute() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .984
19.6.1.3 register_callback_attributes() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .985
19.6.1.4 register_callback_state_var() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .986
19.6.1.5 register_fiber_mapping() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .987
19.6.1.6 register_field_attribute() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .989
19.6.1.7 register_field_attributes() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .990
19.6.1.8 register_field_state_var() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .991
19.6.1.9 register_method_attribute() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .992
19.6.1.10register_method_state_var() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .993
19.6.1.11set_attribute_format() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .995

Specman e Language Reference


1999-2015

19

Product Version 15.1


All Rights Reserved.

19.6.1.12set_attribute_sampling() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .996
19.6.1.13set_label_attribute() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .997
19.6.1.14set_text_attribute() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .998
19.6.1.15set_text_state_var() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .999
19.6.1.16Type tr_sampling_point_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1000
19.6.2 any_unit API extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1001
19.6.2.1 assign_recording_config() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1001
19.6.2.2 get_recording_config() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1002
19.6.2.3 tr_get_attribute_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1002
19.6.2.4 tr_get_state_var_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1004
19.6.3 any_stuct API Extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1004
19.6.3.1 tr_get_attribute_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1005
19.7 Messaging Interfaces Under Deprecation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1006
19.7.1 How Regular Message Actions are Handled . . . . . . . . . . . . . . . . . . . . . . . . .1006
19.7.2 Messaging Procedural Interface Methods . . . . . . . . . . . . . . . . . . . . . . . . . . .1007
19.7.2.1 allocate_tags() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1007
19.7.2.2 get_tags() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1008
19.7.2.3 ignore_tags() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1009
19.7.2.4 set_actions() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1010
19.7.2.5 set_file() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1012
19.7.2.6 set_format() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1013
19.7.2.7 set_screen() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1014
19.7.2.8 set_style() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1015
19.7.2.9 set_trans() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1017
19.7.2.10show_actions() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1018
19.7.2.11show_message() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1019
19.7.2.12show_units() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1020
19.7.3 Methods for Extending accept_message() and format_message() . . . . . . . . .1021
19.7.3.1 get_action_style() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1022
19.7.3.2 get_format() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1022
19.7.3.3 get_message() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1024
19.7.3.4 get_message_action_id() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1025
19.7.3.5 get_tag() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1026
19.7.3.6 get_time() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1026
19.7.3.7 get_verbosity() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1027
19.7.3.8 source_location() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1028
19.7.3.9 source_method_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1030
19.7.3.10source_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1030
19.7.3.11source_struct_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1031

20

Packing and Unpacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1033


20.1 Basic Packing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1034

Specman e Language Reference


1999-2015

20

Product Version 15.1


All Rights Reserved.

20.1.1 A Simple Example of Packing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1034


20.1.2 A Simple Example of Unpacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1036
20.1.3 Packing and Unpacking Scalar Expressions . . . . . . . . . . . . . . . . . . . . . . . . .1038
20.1.4 Packing and Unpacking Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1039
20.1.5 Packing and Unpacking Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1040
20.1.6 Packing and Unpacking Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1041
20.2 Advanced Packing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1044
20.2.1 Using the Predefined pack_options Instances . . . . . . . . . . . . . . . . . . . . . . . .1044
20.2.1.1 packing.low . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1045
20.2.1.2 packing.low_big_endian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1046
20.2.1.3 packing.high . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1047
20.2.1.4 packing.high_big_endian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1048
20.2.1.5 packing.network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1049
20.2.1.6 packing.global_default . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1050
20.2.2 Customizing Pack Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1050
20.2.2.1 reverse_fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1051
20.2.2.2 reverse_list_items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1052
20.2.2.3 scalar_reorder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1052
20.2.2.4 final_reorder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1054
20.2.3 Customizing Packing for a Particular Struct . . . . . . . . . . . . . . . . . . . . . . . . .1056
20.2.4 Bit Slice Operator and Packing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1056
20.2.5 Implicit Packing and Unpacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1057
20.3 How to Debug Packing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1058
20.4 Constructs for Packing and Unpacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1058
20.4.1 pack() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1059
20.4.2 unpack() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1064
20.4.3 swap() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1069
20.4.4 do_pack() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1071
20.4.5 do_unpack() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1075

21

Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1081
21.1 Overview of e Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1081
21.2 define as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1085
21.3 define as computed Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1096
21.3.1 define as computed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1096
21.3.2 Using the reject_match() Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1101
21.3.3 Using the get_current_line_num() and get_current_module() Routines . . . .1103
21.3.4 define as computed Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1105

Specman e Language Reference


1999-2015

21

Product Version 15.1


All Rights Reserved.

21.4 Match Expressions in e Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1109


21.4.1 Literal Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1109
21.4.2 Syntactic Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1110
21.4.3 Regular Expression Operators in Match Expressions . . . . . . . . . . . . . . . . . .1112
21.4.4 Submatch Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1113
21.4.5 Special Literal Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1113
21.4.5.1 Parentheses, Square Brackets and Curly Brackets . . . . . . . . . . . . . .1113
21.4.5.2 Double Quotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1114
21.4.5.3 Semicolons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1114
21.4.6 Submatches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1115
21.4.7 Problematic Match Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1115
21.4.8 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1116
21.5 Tracing Macro Expansion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1117
21.6 Macro Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1118
21.7 Debugging Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1120

22

Preprocessor Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1127


22.1
22.2
22.3
22.4

23

#ifdef, #ifndef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1127


#define . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1130
#undef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1133
Predefined Preprocessor Flags for Specman Version Number . . . . . . . . . . . . . . . . . . .1135
22.4.1 SPECMAN_VERSION_nn_nn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1136
22.4.2 SPECMAN_FULL_VERSION_nn_nn_nnn . . . . . . . . . . . . . . . . . . . . . . . . .1136
22.4.3 SPECMAN_VERSION_nn_nn_OR_LATER . . . . . . . . . . . . . . . . . . . . . . . .1137

Predefined Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1139


23.1 Global Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1140
23.1.1 Test Phase Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1141
23.1.2 Global Method start_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1144
23.1.3 Global Method generate_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1144
23.1.4 Global Method setup_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1145
23.1.5 Global Method run_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1145
23.1.6 Global Method extract_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1146
23.1.7 Global Method check_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1147
23.1.8 Global Method finalize_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1147
23.1.9 Global Method get_timescale() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1148
23.1.10 Global Method is_gui() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1149

Specman e Language Reference


1999-2015

22

Product Version 15.1


All Rights Reserved.

23.1.11 Global Method print_stack_trace() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1149


23.1.12 Global Method simulator_exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1151
23.1.13 Global Method simulator_save() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1152
23.1.14 Global Method sn_plusarg_exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1152
23.1.15 Global Method sn_plusarg_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1154
23.1.16 Global Method update_sys_time() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1156
23.2 Methods of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1157
23.2.1 The init() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1157
23.2.2 The wave_setup() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1159
23.2.3 The setup() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1161
23.2.4 The run() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1162
23.2.5 The extract() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1163
23.2.6 The check() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1164
23.2.7 The finalize() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1165
23.2.8 The pre_save() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1166
23.2.9 The pre_restore() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1167
23.2.10 The post_restore() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1169
23.2.11 The simulator_save() TCM of Sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1171
23.2.12 The remap_tick_access() Method of sys . . . . . . . . . . . . . . . . . . . . . . . . . . . .1173
23.3 Predefined Methods of Any Struct or Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1176
23.3.1 The check() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . . . .1177
23.3.2 The copy() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . . . . .1178
23.3.3 The get_printed_lines() Method of any_struct or any_unit . . . . . . . . . . . . . .1180
23.3.4 The do_print() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . .1181
23.3.5 The extract() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . . .1183
23.3.6 The finalize() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . . .1185
23.3.7 The init() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . . . . . .1186
23.3.8 The quit() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . . . . . .1189
23.3.9 The run() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . . . . . .1192
23.3.10 The rerun() Method of any_struct or any_unit . . . . . . . . . . . . . . . . . . . . . . . .1193
23.4 Procedural API for Temporal Operators on event and expect struct Members . . . . . .1197
23.4.1 do_abort_on_event() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1197
23.4.2 do_stop_on_event() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1199
23.4.3 do_start_on_event() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1200
23.4.4 do_abort_on_expect() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1202
23.4.5 do_stop_on_expect() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1204
23.4.6 do_start_on_expect() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1205

Specman e Language Reference


1999-2015

23

Product Version 15.1


All Rights Reserved.

23.4.7 do_abort_on_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1207


23.4.8 do_stop_on_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1209
23.4.9 do_start_on_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1211
23.4.10 apply_abort_on_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1213
23.4.11 apply_stop_on_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1215
23.4.12 apply_start_on_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1217
23.4.13 do_abort_on_all_events() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1219
23.4.14 do_stop_on_all_events() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1219
23.4.15 do_start_on_all_events() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1219
23.4.16 do_abort_on_all_expects() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1219
23.4.17 do_stop_on_all_expects() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1219
23.4.18 do_start_on_all_expects() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1219
23.4.19 do_abort_on_subtree() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1219
23.4.20 do_stop_on_subtree() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1221
23.4.21 do_start_on_subtree() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1223
23.4.22 propagate_abort_on_subtree() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1225
23.4.23 propagate_stop_on_subtree() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1227
23.4.24 propagate_start_on_subtree() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1229
23.4.25 do_abort_on_all_instance_fields() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1231
23.4.26 do_stop_on_all_instance_fields() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1231
23.4.27 do_start_on_all_instance_fields() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1232
23.5 Coverage Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1232
23.5.1 covers.include_tests() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1233
23.5.2 covers.set_weight() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1234
23.5.3 covers.set_at_least() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1236
23.5.4 covers.set_cover() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1237
23.5.5 covers.set_cover_block() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1240
23.5.6 covers.set_cover_check() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1241
23.5.7 covers.set_per_inst_for_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1243
23.5.8 covers.get_contributing_runs() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1245
23.5.9 covers.get_unique_buckets() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1246
23.5.10 covers.write_cover_file() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1248
23.5.11 covers.compute_overall_grade() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1249
23.5.12 covers.get_overall_grade() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1251
23.5.13 covers.get_ucd_path() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1252
23.5.14 covers.get_test_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1253
23.5.15 covers.get_seed() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1255

Specman e Language Reference


1999-2015

24

Product Version 15.1


All Rights Reserved.

23.6

23.7

23.8

23.9

23.10

24

23.5.16 covers.set_unicov_hier() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1256


23.5.17 covers.set_cross_instance_collection() . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1258
23.5.18 covers.get_top_size_items() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1259
Scheduler Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1260
23.6.1 scheduler.get_current_handle() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1261
23.6.2 scheduler.get_handles_by_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1263
23.6.3 scheduler.get_handles_by_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1265
23.6.4 scheduler.kill() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1267
23.6.5 scheduler.terminate_branch() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1269
23.6.6 scheduler.terminate_thread() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1271
Simulation-Related Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1272
23.7.1 simulator.get_define() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1272
23.7.2 is_stub_required() / get_stub_reason() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1274
Semaphore and Locker Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1276
23.8.1 Using Semaphores and Lockers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1278
23.8.2 How to Use the Semaphore Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1279
23.8.3 up() and down() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1279
23.8.4 try_up() and try_down() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1283
23.8.5 set_value() and get_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1285
23.8.6 set_max_value() and get_max_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1286
23.8.7 lock() and free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1288
Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1292
23.9.1 source_location() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1292
23.9.2 source_method() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1293
23.9.3 writef() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1294
Time Conversion Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1297
23.10.1 to_specman_scale() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1297
23.10.2 from_specman_scale() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1300
23.10.3 to_specman_scale_trunc() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . . .1302
23.10.4 from_specman_scale_trunc() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . .1303
23.10.5 to_real_specman_scale() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . . . .1304
23.10.6 from_real_specman_scale Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . . .1306
23.10.7 double_to_specman_scale() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . . . . .1307
23.10.8 double_from_specman_scale() Pseudo-Method . . . . . . . . . . . . . . . . . . . . . .1309

Importing e Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1311


24.1 import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1311

Specman e Language Reference


1999-2015

25

Product Version 15.1


All Rights Reserved.

25

List Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1319


25.1 Pseudo-Methods Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1319
25.2 Using List Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1320
25.3 Pseudo-Methods to Modify Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1320
25.3.1 add(item) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1321
25.3.2 add(list) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1323
25.3.3 add0(item) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1325
25.3.4 add0(list) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1327
25.3.5 clear() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1329
25.3.6 delete() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1330
25.3.7 fast_delete() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1332
25.3.8 insert(index, item) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1334
25.3.9 insert(index, list) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1335
25.3.10 pop() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1337
25.3.11 pop0() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1338
25.3.12 push() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1339
25.3.13 push0() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1341
25.3.14 resize() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1342
25.4 General List Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1349
25.4.1 all_different() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1350
25.4.2 all_different() (Conditional) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1351
25.4.3 apply() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1353
25.4.4 copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1356
25.4.5 count() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1357
25.4.6 exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1359
25.4.7 field (for List Item) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1360
25.4.8 first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1361
25.4.9 first_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1363
25.4.10 flatten() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1364
25.4.11 get_indices() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1366
25.4.12 has() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1367
25.4.13 is_a_permutation() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1369
25.4.14 is_empty() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1371
25.4.15 last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1372
25.4.16 last_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1374
25.4.17 max() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1376
25.4.18 max_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1377

Specman e Language Reference


1999-2015

26

Product Version 15.1


All Rights Reserved.

25.5

25.6

25.7

25.8

26

25.4.19 max_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1379


25.4.20 min() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1381
25.4.21 min_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1382
25.4.22 min_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1384
25.4.23 reverse() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1386
25.4.24 size() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1388
25.4.25 sort() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1390
25.4.26 sort_by_field() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1392
25.4.27 split() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1393
25.4.28 top() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1397
25.4.29 top0() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1398
25.4.30 unique() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1399
Sublist Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1400
25.5.1 all() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1401
25.5.2 all_indices() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1403
Math and Logic Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1407
25.6.1 and_all() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1407
25.6.2 average() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1408
25.6.3 or_all() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1410
25.6.4 product() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1411
25.6.5 sum() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1413
25.6.6 sum() (Conditional) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1414
List CRC Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1417
25.7.1 crc_8() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1417
25.7.2 crc_32() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1419
25.7.3 crc_32_flip() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1421
Keyed List Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1423
25.8.1 key() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1423
25.8.2 key_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1427
25.8.3 key_exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1428

Set Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1431


26.1 Fundamental Set Operation Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1431
26.1.1 union(set) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1431
26.1.2 intersect(set) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1432
26.1.3 diff(set) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1433
26.2 Set Size Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1434

Specman e Language Reference


1999-2015

27

Product Version 15.1


All Rights Reserved.

26.2.1 set.size() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1434


26.2.2 set.uint_size() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1435
26.2.3 set.size_is_uint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1437
26.3 Set Boundaries Pseudo-Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1438
26.3.1 set.min() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1438
26.3.2 set.max() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1439
26.3.3 set.int_min() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1440
26.3.4 set.int_max() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1441
26.3.5 set.min_is_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1442
26.3.6 set.max_is_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1443
26.3.7 set.uint_min() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1444
26.3.8 set.uint_max() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1445
26.3.9 set.min_is_uint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1446
26.3.10 set.max_is_uint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1447
26.4 Set Pseudo-Methods for Continuous Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1448
26.4.1 set.get_all_ranges() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1448
26.4.2 set.collect_all_ranges() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1449
26.4.3 set.get_range() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1450
26.4.4 set.get_range_below() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1451
26.4.5 set.get_range_above() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1452

27

Predefined Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1455


27.1 Struct ID Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1456
27.1.1 sn_unique_id_for_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1456
27.2 Deep Copy and Compare Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1457
27.2.1 deep_copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1458
27.2.2 deep_compare() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1461
27.2.3 deep_compare_physical() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1466
27.3 Arithmetic Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1469
27.3.1 min() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1469
27.3.2 max() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1471
27.3.3 abs() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1472
27.3.4 odd() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1473
27.3.5 even() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1474
27.3.6 ilog2() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1475
27.3.7 ilog10() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1476
27.3.8 ipow() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1477

Specman e Language Reference


1999-2015

28

Product Version 15.1


All Rights Reserved.

27.4
27.5
27.6
27.7

27.8

27.9

27.3.9 isqrt() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1478


27.3.10 div_round_up() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1480
Routines for Random Distribution of Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1481
Routines Supporting the real Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1482
27.5.1 Arithmetic Routines Supporting Real Type . . . . . . . . . . . . . . . . . . . . . . . . . .1482
Bitwise Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1484
27.6.1 bitwise_op() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1484
String Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1487
27.7.1 append() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1488
27.7.2 appendf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1490
27.7.3 bin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1492
27.7.4 dec() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1493
27.7.5 hex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1494
27.7.6 quote() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1496
27.7.7 str_chop() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1497
27.7.8 str_empty() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1498
27.7.9 str_exactly() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1499
27.7.10 str_insensitive() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1501
27.7.11 str_join() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1502
27.7.12 str_len() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1503
27.7.13 str_lower() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1504
27.7.14 str_match() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1505
27.7.15 str_pad() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1508
27.7.16 str_replace() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1509
27.7.17 str_split() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1512
27.7.18 str_split_all() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1514
27.7.19 str_sub() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1515
27.7.20 str_upper() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1517
27.7.21 to_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1518
Macro-Related Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1520
27.8.1 get_current_line_num() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1520
27.8.2 get_current_module() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1521
27.8.3 str_expand_dots() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1522
27.8.4 reject_match() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1523
Output Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1524
27.9.1 out() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1524
27.9.2 outf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1526

Specman e Language Reference


1999-2015

29

Product Version 15.1


All Rights Reserved.

27.10

27.11
27.12
27.13

27.14

27.9.3 Format String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1528


Configuration Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1530
27.10.1 set_config() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1530
27.10.2 get_config() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1535
27.10.3 write_config() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1536
27.10.4 read_config() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1538
27.10.5 set_retain_state() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1540
27.10.6 get_retain_state() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1541
Agent-Related Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1543
27.11.1 agent_command() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1543
Specman Command Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1544
27.12.1 specman() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1544
OS Interface Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1545
27.13.1 spawn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1545
27.13.2 spawn_check() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1547
27.13.3 system() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1548
27.13.4 output_from() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1549
27.13.5 output_from_check() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1551
27.13.6 get_symbol() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1552
27.13.7 date_time() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1553
27.13.8 getpid() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1554
File Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1555
27.14.1 File Names and Search Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1555
27.14.2 File Descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1556
27.14.3 File Access after a Save/Restore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1556
27.14.4 Low-Level File Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1556
27.14.4.1close() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1557
27.14.4.2flush() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1559
27.14.4.3open() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1561
27.14.4.4read() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1563
27.14.4.5read_lob() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1564
27.14.4.6read_into_lob() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1566
27.14.4.7write() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1568
27.14.4.8write_lob() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1569
27.14.5 General File Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1571
27.14.5.1add_file_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1572
27.14.5.2file_age() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1574
27.14.5.3file_append() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1576
27.14.5.4file_copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1577

Specman e Language Reference


1999-2015

30

Product Version 15.1


All Rights Reserved.

27.14.5.5file_delete() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1579
27.14.5.6file_exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1580
27.14.5.7file_extension() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1582
27.14.5.8file_is_dir() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1583
27.14.5.9file_is_link() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1584
27.14.5.10file_is_readable() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1586
27.14.5.11file_is_regular() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1587
27.14.5.12file_is_temp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1588
27.14.5.13file_is_text() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1590
27.14.5.14file_rename() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1591
27.14.5.15file_size() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1592
27.14.5.16flush_log_file() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1594
27.14.5.17get_text_lines() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1595
27.14.5.18new_temp_file() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1596
27.14.5.19write_string_list() / write_compressed_string_list() . . . . . . . . . . .1597
27.14.6 Reading and Writing Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1599
27.14.6.1read_ascii_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1599
27.14.6.2read_binary_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1601
27.14.6.3write_ascii_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1603
27.14.6.4write_binary_struct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1606
27.15 On-the-Fly Garbage Collection Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1608
27.15.1 do_otf_gc() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1608
27.16 Calling Predefined Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1610
27.16.1 routine() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1610

28

Modeling State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1613


28.1 State Machine Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1613
28.2 State Machine Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1614
28.2.1 state machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1614
28.2.2 state => state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1617
28.2.3 * => state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1618
28.2.4 state action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1619
28.3 Sample State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1620
28.4 Using State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1621
28.4.1 Initializing a State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1622
28.4.2 Terminating a State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1622
28.4.3 Rules for State Transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1624
28.4.4 Nested State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1624
28.4.5 Parallel State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1625

Specman e Language Reference


1999-2015

31

Product Version 15.1


All Rights Reserved.

29

Encapsulation Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1627


29.1
29.2
29.3
29.4

30

package package-name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1627


package type-declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1628
package | protected | private struct-member . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1630
Scope Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1632
29.4.1 :: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1632

Objection Mechanism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1635


30.1 objection_kind enum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1635
30.2 Objection Counter and Objection Total . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1635
30.3 Methods of any_unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1636

e Language Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1639

Specman e Language Reference


1999-2015

32

Product Version 15.1


All Rights Reserved.

e Basics

This chapter describes the structure of an e program, starting with the organization of e code into one or
more files and the four categories of e constructs, and ending with a description of the struct hierarchy.
This chapter also describes the e operators. It contains the following sections:

Lexical Conventions on page 34

Syntactic Elements on page 42

Struct Hierarchy and Name Resolution on page 54

Operator Precedence on page 68

Evaluation Order of Expressions on page 69

Bitwise Operators on page 70

Boolean Operators on page 76

Arithmetic Operators on page 84

Comparison Operators on page 87

String Matching on page 99

Extraction and Concatenation Operators on page 103

Scalar Modifiers on page 118

Special-Purpose Operators on page 123

See Also

Chapter 13 Temporal Expressions

Chapter 2 Data Types

Chapter 27 Predefined Routines

Specman e Language Reference


1999-2015

33
.

Product Version 15.1


All Rights Reserved.

1.1

Lexical Conventions

The following sections describe the lexical conventions of e:

File Structure on page 34

Code Segments on page 34

Comments and White Space on page 35

Literals and Constants on page 35

Names, Keywords, and Macros on page 41

1.1.1

File Structure

e code can be organized in multiple files. File names must be legal e names. The default file extension is
.e. e code files are sometimes referred to as modules. Each module contains at least one code
segment and can also contain comments.

See Also

Names, Keywords, and Macros on page 41

Code Segments on page 34

Comments and White Space on page 35

1.1.2

Code Segments

A code segment is enclosed with a begin-code marker <' and an end-code marker '>. Both the
begin-code and the end-code markers must be placed at the beginning of a line (left most), with no other
text on that same line (no code and no comments). For example, the following three lines of code form
a code segment:
<'
import cpu_test_env;
'>

Several code segments can appear in one file. Each code segment consists of one or more statements.

See Also

Comments and White Space on page 35

Statements on page 43

Specman e Language Reference


1999-2015

34

Product Version 15.1


All Rights Reserved.

1.1.3

Comments and White Space

e files begin as a comment which ends when the first begin-code marker <' is encountered.
Comments within code segments can be marked with double dashes (--) or double slashes (//):
a = 5;
b = 7;

-- This is an inline comment


// This is also an inline comment

The end-code '> and the begin-code <' markers can be used in the middle of code sections, to write
several consecutive lines of comment:
Import the basic test environment for the CPU...
<'
import cpu_test_env;
'>
This particular test requires the code that bypasses bug#72 as
well as the constraints that focus on the immediate instructions.
<'
import bypass_bug72;
import cpu_test0012;
'>

See Also

Code Segments on page 34

1.1.4

Literals and Constants

Literals are numeric, character and string values specified literally in e. Operators can be applied to
literals to create compound expressions. The following categories of literals and constants are supported
in e:

Unsized Numbers on page 36

Sized Numbers on page 37

MVL Literals and the mvl Type on page 37

Predefined Constants on page 39

Literal String on page 40

Literal Character on page 41

Specman e Language Reference


1999-2015

35
.

Product Version 15.1


All Rights Reserved.

See Also

Real Literals on page 160

Predefined Real Constants for Analog Mixed-Signal (AMS) on page 161

1.1.4.1

Unsized Numbers

Unsized numbers are always positive and zero-extended unless preceded by a hyphen. Decimal
constants are treated as signed integers and have a default size of 32 bits. Binary, hex, and octal
constants are treated as unsigned integers, unless preceded by a hyphen to indicate a negative number,
and have a default size of 32 bits. If the number cannot be represented in 32 bits then it is represented as
an unbounded integer. See Infinite (Unbounded or Long) Integers on page 141 for more information.
The notations shown in Table 1-1 can be used to represent unsized numbers.
Table 1-1

Representing Unsized Numbers in Expressions

Notation

Legal Characters

Examples

Decimal integer

Any combination of 0-9 possibly


preceded by a hyphen - for negative
numbers. An underscore (_) can be added
anywhere in the number for readability.

12, 55_32, -764

Binary integer

Any combination of 0-1 preceded by 0b.


An underscore (_) can be added anywhere
in the number for readability.

0b100111,
0b1100_0101

Hexadecimal integer

Any combination of 0-9 and a-f preceded


by 0x. An underscore (_) can be added
anywhere in the number for readability.

0xff,
0x99_aa_bb_cc

Octal integer

Any combination of 0-7 preceded by 0o.


An underscore (_) can be added anywhere
in the number for readability.

0o66_123

K (kilo: multiply by
1024)

A decimal integer followed by a K or k.


For example, 32K = 32768.

32K, 32k, 128k

M (mega: multiply by
1024*1024)

A decimal integer followed by an M or m.


For example, 2m = 2097152.

1m, 4m, 4M

See Also

Literals and Constants on page 35

Specman e Language Reference


1999-2015

36

Product Version 15.1


All Rights Reserved.

1.1.4.2

Sized Numbers

A sized number is a notation that defines a literal with a specific size in bits. The syntax is as follows:
width-number ' (b|o|d|h|x) value-number
The width number is a decimal integer specifying the width of the literal in bits. The value number is the
value of the literal and can be specified in one of four radixes, as shown in Table 1-2.
Note If the value number is more than the specified size in bits, its most significant bits are ignored.
If the value number is less that the specified size, it is padded by zeros.
Table 1-2

Radix Specification Characters

Radix

Represented By

Example

Binary

A leading 'b or 'B

8'b11001010

Octal

A leading 'o or 'O

6'o45

Decimal

A leading 'd or 'D

16'd63453

Hexadecimal

A leading 'h or 'H or 'x or 'X

32'h12ffab04

See Also

Literals and Constants on page 35

1.1.4.3

MVL Literals and the mvl Type

An MVL literal is based on the mvl type, which is a predefined enumerated scalar type in Specman. The
mvl type is defined as follows:
type mvl: [MVL_U,MVL_X,MVL_0,MVL_1,MVL_Z,MVL_W,MVL_L,MVL_H,MVL_N];
Note

MVL_N represents dont care.

The mvl type is a superset of the capabilities provided by the @x and @z syntax allowed in HDL tick
notation. For example, if a port is defined as type list of mvl, you can assign values with the $ access
operator:
sig$ = {MVL_X;MVL_X;MVL_X}; -- HDL tick notation is 'sig@x' = 0x3

If the port is a numeric type (uint, int, and so on), you can assign mvl values using the predefined MVL
methods for ports. For example:
sig.put_mvl_list({MVL_X;MVL_X;MVL_X});

Specman e Language Reference


1999-2015

37
.

Product Version 15.1


All Rights Reserved.

An MVL literal, which is a literal of type list of mvl, provides a more convenient syntax for assigning
MVL values. The syntax of an MVL literal is as follows:
width-number ' (b|o|h) value-number
The width number is an unsigned decimal integer specifying the size of the list. The value number is any
sequence of digits that are legal for the base, plus x, z, u, l, h, w, n.
Syntax rules:

A single digit represents 4 bits in hexadecimal base, 3 bits in octal base and 1 bit in binary base.
Similarly, the letters x, z, u, l, h, w, n represent 4 identical bits (for hexadecimal), 3 identical bits (for
octal), or 1 bit (for binary). For example, 8h1x is equivalent to 8b0001xxxx.
If the size of the value is smaller than the width, the value is padded to the left. A most significant
bit (MSB) of 0 or 1 causes zero padding. If the MSB of the literal is x, z, u, l, h, w or n, then that mvl
value is used for padding.
If the size of the value is larger than the size specified for the list, the value is truncated leaving the
LSB of the literal.
An underscore can be used for breaking up long numbers to enhance readability. It is legal inside the
size and inside the value. It is illegal at the beginning of the literal, between the base and the value,
and between the single quote (') and the base.

Examples
32'hffffxxxx
32'HFFFFXXXX
//16'_b1100uuuuu
--illegal because (_) is between () and base
19'oL0001
14'D123
64'bz_1111_0000_1111_0000

Notes

Decimal literals are not supported.


White space is not allowed as a separator between the width number and base or between the base
and the value.

The base and the value are not case sensitive.

Size and base have to be specified.

In the context of a Verilog comparison operator (!== or ===) or HDL tick access ('data' = 32'bx),
only the 4-value subset is supported (0, 1, X, Z).
Verilog simulators support only the 4-value logic subset.
An MVL literal of size 1 is of type list of mvl that has one element. It is not of type mvl. Thus, you
cannot assign an MVL literal to a variable or field of type mvl:

Specman e Language Reference


1999-2015

38

Product Version 15.1


All Rights Reserved.

var m: mvl = 1'bz; -- illegal; MVL_Z must be assigned

Syntactically, the same expression may be of a numeric type or MVL literal. For example, 1b1 may
represent either the number 1 or a list of MVL with the value {MVL_1}. Specman extracts the type of a
given literal from the context. A literal is considered to be an MVL literal when:

The literal is assigned to a list of mvl, for example:


var v2: list of mvl = 16'b1;

When the literal is passed to a method that receives a list of mvl

When the literal is assigned to a port of type list of mvl using the $ operator

When the literal is compared to list of mvl, for example:

When the literal is compared using the === and !== operators, for example:

assert v == 4'buuuu;
assert 's' === 4'bz; -- limited to the 4-value subset

When the literal is used in an HDL tick access assignment, for example:
's' = 8'bx1z; -- limited to the 4-value subset

When the literal is an argument for a Verilog task, for example:


'task1'(8'h1x);)

When the literal is used in a list operation, for example


l.add(32'b0)

If the type of the expression, according to the context, is numeric, or if the type cannot be extracted from
the context, the default type remains uint, for example:
print 2'b11; -- prints unsigned integer value 3
print 2'bxx; -- syntax error
pack(NULL, 32'z) -- error

Note

The type-casting operations as_a() and is a do not propagate the context.

See Also

Scalar Types on page 138

1.1.4.4

Predefined Constants

A set of constants is predefined in e, as shown in Table 1-3.

Specman e Language Reference


1999-2015

39
.

Product Version 15.1


All Rights Reserved.

Table 1-3

Predefined Constants

Constant

Description

TRUE

For Boolean variables and expressions.

FALSE

For Boolean variables and expressions.

NULL

For structs, specifies a NULL pointer. For character strings, specifies an empty
string.

UNDEF

An integer value of -1. Indicates NONE where an index is expected.

MAX_INT

Represents the largest 32-bit int (231 -1).

MIN_INT

Represents the smallest 32-bit int (-231).

MAX_UINT

Represents the largest 32-bit uint (232-1).

See Also

Literals and Constants on page 35

1.1.4.5

Literal String

A literal string is a sequence of zero or more ASCII characters enclosed by double quotes ().
The special escape sequences shown in Table 1-4 are allowed.
Table 1-4

Escape Sequences in Strings

Escape Sequence

Meaning

\n

New-line

\t

Tab

\f

Form-feed

Quote

\\

Backslash

\r

Carriage-return

See Also

Literals and Constants on page 35

Specman e Language Reference


1999-2015

40

Product Version 15.1


All Rights Reserved.

1.1.4.6

Literal Character

A literal character is a single ASCII character, enclosed in quotation marks and preceded by 0c. This
expression evaluates to the integer value that represents this character. For example, the literal character
shown below is the single ASCII character a and evaluates to 0x0061.
var u: uint(bytes:2) = 0c"a";

Note

Literal characters can only be assigned to integers or unsigned integers without explicit casting.

See Also

Literals and Constants on page 35

1.1.5

Names, Keywords, and Macros

The following sections describe the legal syntax for names and macros:

Legal e Names on page 41

Macros on page 42

HDL Object Names in the Specman Integrators Guide

1.1.5.1

Legal e Names

User-defined names in e code consist of a case-sensitive combination of any length of the characters
A-Z, a-z, 0-9, and underscore. They must begin with a letter:

Names beginning with an underscore have a special meaning in e and should not be used. There are
limitations on accessing objects whose name begins with an underscore. For example, you cannot
highlight in the debugger or print a variable whose name begins with an underscore.
Names beginning with a number are not allowed.

The syntax of an e module name (a file name) is the same as the syntax of UNIX file names, with the
following exceptions:

@ and ~ are not allowed as the first character of a file name.

[, ], {, } are not allowed in file names.

Only one . is allowed in a file name.

Note Many ASCII characters are not handled correctly by some UNIX commands when used in file
names. These characters include control characters, spaces, and characters reserved for command line
parsing, such as -, |, and <.

Specman e Language Reference


1999-2015

41
.

Product Version 15.1


All Rights Reserved.

Note Naming an e module patch.e or test.e can cause problems when you try to load the compiled
file. If the module is to be compiled, do not name it patch.e or test.e.

1.1.5.2

Macros

e macros (created with the define statement) can be defined with or without an initial ` character. There
are two important characteristics of e macros defined with an initial ` character:

They share the same namespace as Verilog macros.

You must always include the ` character when you reference the name.

Thus, if you import a file of Verilog macros containing the following macro:
'define WORD_WIDTH 8

defining the following e macro results in a name conflict:


define `WORD_WIDTH 16;

With either macro defined, the correct way to reference it is as follows:


struct t {
f: uint (bits: `WORD_WIDTH);
};

See Also

Chapter 22 Preprocessor Directives

HDL Object Names in the Specman Integrators Guide

1.2

Syntactic Elements

Every e construct belongs to a construct category that determines how the construct can be used. There
are four categories of e constructs:

Specman e Language Reference


1999-2015

42

Product Version 15.1


All Rights Reserved.

Statements

Statements are top-level constructs and are valid within the begin-code <'
and end-code '> markers. See Statements on page 43 for a list and brief
description of e statements.

Struct members

Struct members are second-level constructs and are valid only within a
struct definition. See Struct Members on page 45 for a list and brief
description of e struct members.

Actions

Actions are third-level constructs and are valid only when associated with
a struct member, such as a method or an event. See Actions on page 46
for a list and brief description of e actions.

Expressions

Expressions are lower-level constructs that can be used only within


another e construct. See Expressions on page 52 for a list and brief
description of e expressions.

The syntax hierarchy roughly corresponds to the level of indentation shown below:
statements
struct members
actions
expressions

See Also

Statements on page 43

Struct Members on page 45

Actions on page 46

Expressions on page 52

1.2.1

Statements

Statements are the top-level syntactic constructs of the e language and perform the functions related to
extending the e language and interface with the simulator.
Statements are valid within the begin-code <' and end-code '> markers. They can extend over several
lines and are separated by semicolons. For example, the following code segment has two statements:
<'
import bypass_bug72;
import cpu_test0012;
'>

Specman e Language Reference


1999-2015

43
.

Product Version 15.1


All Rights Reserved.

In general, within a given e module, statements can appear in any order. However, import or verilog
import statements must appear before any other statements, except preprocessor directives and package
statements.
Here is the complete list of e statements:
struct on page 216

Defines a new data structure.

type

Defines an enumerated data type or scalar subtype.


See type enumerated scalar on page 183, type
scalar subtype on page 185, or type sized scalar on
page 187

extend

Modifies a previously defined struct or type. See


extend type on page 219 or extend type on page
189

define

Extends the e language by defining new commands,


actions, expressions, or any other syntactic element.
See Chapter 21 Macros, define as on page 1085, or
define as computed Macro on page 1096.

#ifdef, #ifndef on page 1127

Used together with define statements to place


conditions on the e parser.

routine ... is C routine in the Specman

Declares a user-defined C routine that you want to


call from e.

Integrators Guide

C export in the Specman Integrators Guide Exports an e declared type or method to C.


import on page 1311

Reads in an e file.

verilog import on page 840

Reads in Verilog macro definitions from a file.

verilog code on page 835

Writes Verilog code to the stubs file, which is used to


interface e programs with a Verilog simulator.

verilog time on page 847

Specifies Verilog simulator time resolution.

verilog variable reg | wire on page 849

Specifies a Verilog register or wire that you want to


drive from e.

verilog variable memory on page 858

Specifies a Verilog memory that you want to access


from e.

verilog function on page 837

Specifies a Verilog function that you want to call


from e.

verilog task on page 844

Specifies a Verilog task that you want to call from e.

vhdl code on page 863

Writes VHDL code to the stubs file, which is used to


interface e programs with a VHDL simulator.

Specman e Language Reference


1999-2015

44

Product Version 15.1


All Rights Reserved.

vhdl driver on page 865

Used to drive a VHDL signal continuously via the


resolution function.

vhdl function on page 872

Declares a VHDL function defined in a VHDL


package.

vhdl procedure on page 876

Declares a VHDL procedure defined in a VHDL


package.

vhdl time on page 885

Specifies VHDL simulator time resolution.

See Also

Struct Members on page 45

Actions on page 46

Expressions on page 52

1.2.2

Struct Members

Struct member declarations are second-level syntactic constructs of the e language that associate the
entities of various kinds with the enclosing struct.
Struct members can only appear inside a struct type definition statement (see struct on page 216). They
can extend over several lines and are separated by semicolons. For example, the following struct
packet has two struct members, len and data:
<'
struct packet{
%len: int;
%data[len]: list of byte;
};
'>

A struct can contain multiple struct members of any type in any order. Here is a brief description of e
struct members:
field declaration

Defines a data entity that is a member of the enclosing struct and has an
explicit data type.

method declaration

Defines an operational procedure that can manipulate the fields of the


enclosing struct and access runtime values in the DUT.

subtype declaration

Defines an instance of the parent struct in which specific struct


members have particular values or behavior.

Specman e Language Reference


1999-2015

45
.

Product Version 15.1


All Rights Reserved.

constraint declaration

Influences the distribution of values generated for data entities and the
order in which values are generated.

coverage declaration

Defines functional test goals and collects data on how well the testing is
meeting those goals.

temporal declaration

Defines e events and their associated actions.

See Also

Defining Fields on page 225

Rules for Extending Methods in Creating e Testbenches

Creating Subtypes with When on page 241

Defining Constraints on page 617

Defining Coverage Groups on page 735

Chapter 14 Temporal Struct and Unit Members

1.2.3

Actions

e actions are lower-level procedural constructs that can be used in combination to manipulate the fields
of a struct or exchange data with the DUT.
Actions can extend over several lines and are separated by semicolons. An action block is a list of
actions separated by semicolons and enclosed in curly brackets, { }.
Actions must be associated with a struct member, specifically a method or an event, or issued
interactively as commands at the command line. Here is an example of an action (an invocation of a
method, transmit()) associated with an event, xmit_ready. Another action, out() is associated with the
transmit() method.
<'
struct packet{
event xmit_ready is rise('top.ready');
on xmit_ready {
transmit(};
};
transmit() is {
out("transmitting packet...");
};
};
'>

The following sections describe the e actions:

Specman e Language Reference


1999-2015

46

Product Version 15.1


All Rights Reserved.

Creating or Modifying Variables on page 47

Executing Actions Conditionally on page 48

Executing Actions Iteratively on page 48

Controlling Program Flow on page 49

Invoking Methods and Routines on page 49

Performing Time-Consuming Actions on page 50

Generating Data Items on page 51

Detecting and Handling Errors on page 51

Printing on page 52

1.2.3.1

Creating or Modifying Variables

var on page 550

Defines a local variable.

= on page 552

Assigns or samples values of fields, local variables, or HDL objects.

op= on page 554

Performs a complex assignment (such as add and assign, or shift and


assign) of a field, local variable, or HDL object.

force on page 886

Forces a Verilog net or wire to a specified value, over-riding the value


from driven from the DUT.

release on page 892

Releases the Verilog net or wire that was previously forced.

See Also

Executing Actions Conditionally on page 48

Executing Actions Iteratively on page 48

Controlling Program Flow on page 49

Invoking Methods and Routines on page 49

Performing Time-Consuming Actions on page 50

Generating Data Items on page 51

Detecting and Handling Errors on page 51

Printing on page 52

Specman e Language Reference


1999-2015

47
.

Product Version 15.1


All Rights Reserved.

1.2.3.2

Executing Actions Conditionally

if then else on page 561

Executes an action block if a condition is met and a different action


block if it is not.

case labeled-case-item on Executes one action block out of multiple action blocks depending on
page 563
the value of a single expression.
case bool-case-item on
page 566

Evaluates a list of Boolean expressions and executes the action block


associated with the first expression that is true.

See Also

Creating or Modifying Variables on page 47

Executing Actions Iteratively on page 48

Controlling Program Flow on page 49

Invoking Methods and Routines on page 49

Performing Time-Consuming Actions on page 50

Generating Data Items on page 51

Detecting and Handling Errors on page 51

Printing on page 52

1.2.3.3

Executing Actions Iteratively

while on page 568

Executes an action block repeatedly until a Boolean expression


becomes FALSE.

repeat until on page 570

Executes an action block repeatedly until a Boolean expression


becomes TRUE.

for each in on page 572

For each item in a list that is a specified type, executes an action


block.

for from to on page 577

Executes an action block for a specified number of times.

for on page 579

Executes an action block for a specified number of times.

for each line in file on page Executes an action block for each line in a file.
581
for each file matching on
page 582

Executes an action block for each file in the search path.

See Also

Creating or Modifying Variables on page 47

Specman e Language Reference


1999-2015

48

Product Version 15.1


All Rights Reserved.

Executing Actions Conditionally on page 48

Controlling Program Flow on page 49

Invoking Methods and Routines on page 49

Performing Time-Consuming Actions on page 50

Generating Data Items on page 51

Detecting and Handling Errors on page 51

Printing on page 52

1.2.3.4

Controlling Program Flow

break on page 584

Breaks the execution of the enclosing loop.

continue on page 585

Stops execution of the enclosing loop and continues with the next
iteration of the same loop.

See Also

Creating or Modifying Variables on page 47

Executing Actions Conditionally on page 48

Executing Actions Iteratively on page 48

Invoking Methods and Routines on page 49

Performing Time-Consuming Actions on page 50

Generating Data Items on page 51

Detecting and Handling Errors on page 51

Printing on page 52

1.2.3.5

Invoking Methods and Routines

method() on page 540

Calls a regular method.

tcm() on page 535

Calls a TCM.

start tcm() on page 537

Launches a TCM as a new thread (a parallel process).

routine() on page 1610

Calls an e predefined routine.

Specman e Language Reference


1999-2015

49
.

Product Version 15.1


All Rights Reserved.

Calling C Routines from e in the

Describes how to call user-defined C routines.

Specman Integrators Guide


compute method() on page 542

Calls a value-returning method without using the value


returned.

return on page 543

Returns immediately from the current method to the


method that called it.

See Also

Creating or Modifying Variables on page 47

Executing Actions Conditionally on page 48

Executing Actions Iteratively on page 48

Controlling Program Flow on page 49

Performing Time-Consuming Actions on page 50

Generating Data Items on page 51

Detecting and Handling Errors on page 51

Printing on page 52

1.2.3.6

Performing Time-Consuming Actions

emit on page 666

Causes a named event to occur.

sync on page 725

Suspends execution of the current TCM until the temporal expression


succeeds.

wait on page 728

Suspends execution of the current time-consuming method until a given


temporal expression succeeds.

all of on page 730

Executes multiple action blocks concurrently, as separate branches of a


fork. The action following the all of action is reached only when all
branches of the all of have been fully executed.

first of on page 732

Executes multiple action blocks concurrently, as separate branches of a


fork. The action following the first of action is reached when any of the
branches in the first of has been fully executed.

state machine on page Defines a state machine.


1614

See Also

Creating or Modifying Variables on page 47

Executing Actions Conditionally on page 48

Specman e Language Reference


1999-2015

50

Product Version 15.1


All Rights Reserved.

Executing Actions Iteratively on page 48

Controlling Program Flow on page 49

Invoking Methods and Routines on page 49

Generating Data Items on page 51

Detecting and Handling Errors on page 51

Printing on page 52

1.2.3.7

Generating Data Items

gen...keeping on page Generates a value for an item, while considering all relevant constraints.
653

See Also

Creating or Modifying Variables on page 47

Executing Actions Conditionally on page 48

Executing Actions Iteratively on page 48

Controlling Program Flow on page 49

Invoking Methods and Routines on page 49

Performing Time-Consuming Actions on page 50

Detecting and Handling Errors on page 51

Printing on page 52

1.2.3.8

Detecting and Handling Errors

check that on page 588

Checks the DUT for correct data values.

dut_error() and
dut_errorf() on page 591

Defines a DUT error message string.

assert on page 614

Issues an error message if a specified Boolean expression is not true.

warning() on page 606

Issues a warning message.

error() on page 607

Issues an error message when a user error is detected.

fatal() on page 609

Issues an error message, halts all activities, and exits immediately.

try on page 612

Catches errors and exceptions.

See Also

Creating or Modifying Variables on page 47

Specman e Language Reference


1999-2015

51
.

Product Version 15.1


All Rights Reserved.

Executing Actions Conditionally on page 48

Executing Actions Iteratively on page 48

Controlling Program Flow on page 49

Invoking Methods and Routines on page 49

Performing Time-Consuming Actions on page 50

Generating Data Items on page 51

Printing on page 52

1.2.3.9

Printing

print in the Specman Command


Reference

Prints a list of expressions.

set_config() on page 1530

Sets options for various categories, including printing.

See Also

Creating or Modifying Variables on page 47

Executing Actions Conditionally on page 48

Executing Actions Iteratively on page 48

Controlling Program Flow on page 49

Invoking Methods and Routines on page 49

Performing Time-Consuming Actions on page 50

Generating Data Items on page 51

Detecting and Handling Errors on page 51

1.2.4

Expressions

Expressions are constructs that combine operands and operators to represent a value. The resulting value
is a function of the values of the operands and the semantic meaning of the operators.
A few e expressions, such as expressions that restrict the range of valid values of a variable, must
evaluate to constants at compile time. More typically, expressions are evaluated at run time, resolved to
a value of some type, and assigned to a variable or field of that type. Strict type checking in e is enforced.
Each expression must contain at least one operand, which can be:

A literal value

A constant

Specman e Language Reference


1999-2015

52

Product Version 15.1


All Rights Reserved.

An e entity, such as a method, field, list, or struct

An HDL entity, such as a signal

A compound expression applies one or more operators to one or more operands.


A compound expression applies one or more operators to one or more operands. It is important to avoid
using expressions that so long as to create parsing problems. For more information, see Avoiding
problematic long expression parsing on page 53.

See Also

Chapter 2 Data Types

1.2.4.1

Avoiding problematic long expression parsing

The parsing of very long expressions in e code can consume lots of cpu and memory resources, and in
some situations (especially on 32-bit platforms), lead to an out-of-memory crash. This is especially the
case if the long expression contains a real syntax error, but it can also happen with very long legal
expressions.
To avoid the problem it is recommended that you do the following:

Use parentheses in long expressions, to make the ordering between operators explicit.
This makes the code more readable and thus less error prone. Further, in some cases this also causes
Specman parser to handle such expressions faster.

If needed, break the long expression into several shorter expressions, and use temporary variables to
combine between them.

If Specman enters a too-long calculation while handling an expression, it issues a a notification (default:
WARNING). You can then choose to stop the parsing or ignore the warning. (You can also change the
notification severity.) For more information, see Specman Deprecation and Backwards Compatability.

Example 1
The following code contains a syntax error, and trying to load or compile this code leads to the behavior
described above.
print x == 0 or x == 1 or x == 2 or x == 3 or x == 4 or x == 5 or x == 6 or x
== 7 or x == 8 or x == 9 or x == 10 or x == 11 or x == 12 or x == 13 or x
== 14 or x == 15 or x == 16 or x == 17 or x == 18 or x == 19 or;

Adding parentheses to the expression makes the syntax error easy to spot and therefore easy to correct
the expression has an extra "or" at the end, which must be deleted. Furthermore, use of parentheses
can also speed up the parsing.
Specman e Language Reference
1999-2015

53
.

Product Version 15.1


All Rights Reserved.

print
or (x
or (x
or (x

(x
==
==
==

== 0) or (x == 1) or (x == 2) or (x == 3) or (x == 4) or (x == 5)
6) or (x == 7) or (x == 8) or (x == 9) or (x == 10) or (x == 11)
12) or (x == 13) or (x == 14) or (x == 15) or (x == 16)
17) or (x == 18) or (x == 19)or;

Example 2
The following legal code contains a too-long expression that might result in Specman failing to load or
compile the code.
print a1 + b1 << a2 + b2 << a3 + b3 << a4 + b4 << a5 + b5 << a6 + b6 << a7 +
b7 << a8 + b8 << a9 + b9 << a10 + b10 << a11 + b11 << a12 + b12 << a13 +
b13 << a14 + b14 << a15 + b15 << a16 + b16 << a17 + b17 << a18 + b18 << a19
+ b19 << a20 + b20;

However, the above code can be broken into smaller expressions to speed up its parsing:
var tmp1 := a1 + b1 << a2 + b2 << a3 + b3 << a4 + b4 << a5 + b5 << a6 + b6 <<
a7 + b7 << a8 + b8 << a9 + b9 << a10 + b10;
var tmp2 := a11 + b11 << a12 + b12 << a13 + b13 << a14 + b14 << a15 + b15 <<
a16 + b16 << a17 + b17 << a18 + b18 << a19 + b19 << a20 + b20;
print tmp1 << tmp2;

1.3

Struct Hierarchy and Name Resolution

The following sections explain the struct hierarchy of an e program and how to reference entities within
the program:

Struct Hierarchy on page 54

Referencing e Entities on page 58

Implicit Variables on page 62

Name Resolution Rules on page 65

1.3.1

Struct Hierarchy

Because structs can be instantiated as the fields of other structs, a typical e program has many levels of
hierarchy. Every e program contains several predefined structs as well as user-defined structs. Figure 1-1
shows the partial hierarchy of a typical e program. The predefined structs are shown in bold.

Specman e Language Reference


1999-2015

54

Product Version 15.1


All Rights Reserved.

Figure 1-1

Diagram of Struct Hierarchy


global

files

covers

packing

sys

scheduler

session

simulator

switch

ctrl_stub

port_stub1

sender

port_stub2

port_stub3

port_stub4

listener

The predefined structs are described in more detail in the following sections:

Global Struct on page 55

Sys Struct on page 56

Files Struct on page 56

Covers Struct on page 56

Packing Struct on page 57

Scheduler Struct on page 57

Session Struct on page 57

Simulator Struct on page 58

1.3.1.1

Global Struct

The predefined struct global is the root of all e structs. All predefined structs and most predefined
methods are part of the global struct.
Predefined methods for the global struct are described in Global Methods on page 1140.
It is highly recommended that you do not extend the global struct.

Specman e Language Reference


1999-2015

55
.

Product Version 15.1


All Rights Reserved.

1.3.1.2

Sys Struct

The system struct is instantiated under global as sys.


Predefined methods for the sys struct are described in Methods of sys on page 1157.
All fields and structs in sys not marked by an exclamation point (!) are generated automatically during
the generate_test phase. Any structs or fields outside of sys that need generation must be generated
explicitly.

Time
The time is stored in one of two fields:

A 64-bit integer field named sys.time

A field of type real named sys.realtime, which can hold a more precise simulator time than sys.time.

In standalone mode, time is measured in Specman ticks. In this case, sys.realtime and sys.time contain
the same value.
When Specman is linked with an event-driven simulator, sys.time shows the current simulator time,
rounded as per the Specman timescale, while sys.realtime shows the current simulator time rounded as
per Specman precision.
When Specman is linked with a cycle-based simulator, sys.time shows the current simulator cycle.
Notes

sys.time and sys.realtime are influenced by the current timescale. See verilog time on page 847 and
vhdl time on page 885 for information on how Specman determines the timescale.
For more information about time literals, see Time Literals and Predefined Time Types in Running
Specman with Incisive Simulator

1.3.1.3

Files Struct

The files struct provides predefined routines for manipulating files. Predefined routines provided with
the files struct are described in File Routines on page 1555.

1.3.1.4

Covers Struct

The covers struct provides predefined methods for controlling the collection and analysis of Specman
coverage. Predefined methods provided with the covers struct are described in Coverage Methods on
page 1232.

Specman e Language Reference


1999-2015

56

Product Version 15.1


All Rights Reserved.

1.3.1.5

Packing Struct

Packing and unpacking prepare e data sent to or received from the DUT. Under the packing struct are
five predefined structs. You can create your own packing order by copying one of these structs and
modifying one or more of its parameters.
Predefined methods and pseudo-methods provided with the packing struct are described in Constructs
for Packing and Unpacking on page 1058.

1.3.1.6

Scheduler Struct

The scheduler struct contains predefined methods that allow you to access active TCMs and terminate
them. Predefined methods provided with the scheduler struct are described in Scheduler Methods on
page 1260.

1.3.1.7

Session Struct

The session struct holds the status of the current simulator session, related information, and events. You
can print the session struct to see the types of information that are stored in this struct by typing the
following at the Specman prompt:
print session

Fields available in the session struct that are of general interest include:

session.user_time

session.system_time

session.specman_memory

session.check_ok

session.events

The first three fields listed above help you determine the time and memory used in a particular session.
The following sections describe the check_ok field and the events field.

session.check_ok
This field is of Boolean type, and is set TRUE after every check, if the check succeeds. Otherwise, it is
set to FALSE. This field allows you to extend checking of a behavior without the need to duplicate the
if clause.
The following example show how this is accomplished.
run() is also {
check that mlist.size() > 0
Specman e Language Reference
1999-2015

57
.

Product Version 15.1


All Rights Reserved.

else dut_error("Empty list");


if session.check_ok then {
check that mlist[0] == 0xff
else dut_error("Error at index 0");
};
};

session.events
This field contains the names of all user-defined events that occurred during the test, and how many
times each user-defined event occurred. The name of the event is preceded by the struct type and a
double underscore:
struct_type__event_name
You can view the events coverage by selecting the session.events group in the coverage GUI, or by
entering the command:
show cover session.events

If an event is defined in a when subtype, the name of the event in the session.events field is prefixed by
the subtype and a double underscore:
subtype__struct_type__event_name

1.3.1.8

Simulator Struct

The simulator struct controls the HDL simulator and has a predefined method that allows access to
Verilog macros at run time. Predefined methods provided with the simulator struct are described in
Simulation-Related Methods on page 1272.

1.3.2

Referencing e Entities

The following sections describe how to reference e entities:

Structs and Fields on page 59

Method and Routine Names on page 60

Enumerated Type Values on page 61

Specman e Language Reference


1999-2015

58

Product Version 15.1


All Rights Reserved.

1.3.2.1

Structs and Fields

Any user-defined struct can be instantiated as a field of the sys struct or of another struct. Thus every
instantiated struct and its fields have a place in the struct hierarchy and their names include a path
reflecting that place.
The keep constraints in the following example show the use of paths to identify the fields u and kind:
<'
struct switch {
ctrl: ctrl_stub;
port: port_stub;
keep soft port.sender.cell.u == 0xff;
keep ctrl.init_command.kind == RD;
};
struct ctrl_stub {
init_command: ctrl_cmd;
};
struct simplex {
kind: [TX, RX];
cell: cell;
};
struct port_stub {
sender: TX simplex;
listener: RX simplex;
};
struct cell {
u: uint;
};
struct ctrl_cmd {
kind: [RD, WR];
addr: int;
};
extend sys {
switch : switch;
};
'>

Notes

The name of the global struct can be omitted from the path to a field or a struct.
The name of the enclosing struct is not included in the path if the current struct is the enclosing struct.
For example, prefixing the name port.sender.cell.u in the example above with the name of the
enclosing struct, switch, is an error.

Specman e Language Reference


1999-2015

59
.

Product Version 15.1


All Rights Reserved.

In certain contexts, you can use the implicit variables me or it in the path to refer to the enclosing
struct. For example, prefixing the name port.sender.cell.u in the example above with me is legal. See
Implicit Variables on page 62 for more information.
A special syntax is required to reference struct subtypes and fields under struct subtypes. This syntax
is described in Struct Subtypes on page 150.

See Also

Struct Subtypes on page 150

Implicit Variables on page 62

. on page 128

Packages as Namespaces for Types in Creating e Testbenches

1.3.2.2

Method and Routine Names

The names of all methods and routines must be followed immediately by parentheses, both when you
define the method and when you call it.
The predefined methods of any struct, such as pre_generate() or init(), and all user-defined methods,
are associated with a particular struct. Thus, like structs and fields, every user-defined method has a
place in the struct hierarchy and its name includes a path reflecting that place.
The example below illustrates the names used to call user-defined and predefined methods.
<'
struct meth {
%size: int;
%taken: int;
final get_free(size: int, taken: int): int is {
result = size - taken;};
};
extend sys {
!area: int;
mi: meth;
post_generate() is also {
sys.area = sys.mi.get_free(sys.mi.size, sys.mi.taken);
print sys.area;
};
};
'>

Specman e Language Reference


1999-2015

60

Product Version 15.1


All Rights Reserved.

Some predefined methods, such as the methods used to manipulate lists, are pseudo-methods. They are
not associated with a particular struct. These methods are called by appending their name to the
expression that you want to manipulate. Here is an example of how to call the list pseudo-method .size():
<'
struct meth {
%data: list of int;
keep data.size() <= 10;
};
'>

See Also

Invoking Methods and Routines on page 49

Name Resolution Rules on page 65

1.3.2.3

Enumerated Type Values

Names for enumerated type values must be unique within each type. For example, defining a type as
my_type: [a, a, b] results in an error because the name a is not unique.
However, the same name can be used in more than one enumerated type. For example, the following two
enumerated types define the same value names:
type destination: [a, b, c, d];
type source: [a, b, c, d];

To refer to an enumerated type value in a struct where no values are shared between the enumerated
types, you can use just the value name. In structs where more than one enumerated field can have the
same value, you must use the following syntax to refer to the value when the type is not clear from the
context:
type_name'value

In the following keep constraint, it is clear that the type of dest is destination, so you can use just the
value name b:
type destination: [a, b, c, d];
type source: [a, b, c, d];
struct packet {
dest: destination;
keep me.dest == b;
};

Specman e Language Reference


1999-2015

61
.

Product Version 15.1


All Rights Reserved.

However, because the type of the variable tmp below is not specified, it is necessary to use the full
name for the enumerated type value destination'b:
m() is {
var tmp := destination'b;
};

See Also

Enumerated Scalar Types on page 145

Packages as Namespaces for Types in Creating e Testbenches

1.3.3

Implicit Variables

Many e constructs create implicit variables. The scope of these implicit variables is the construct that
creates them. Two of these implicit variables, me and it, are used in pathnames when referencing e
entities.
This section describes the implicit variables:

it on page 62

me on page 63

result on page 64

index on page 64

Note With the exception of result, you cannot assign values to implicit variables. An assignment such
as me = packet generates an error.

1.3.3.1

it

The constructs that create the implicit variable it are:

list pseudo-methods

for each

gen...keeping

keep for each

keep .is_all_iterations()

new with

list with key declaration

Specman e Language Reference


1999-2015

62

Product Version 15.1


All Rights Reserved.

The implicit variable it always refers to the current item.


Wherever it.field can be used, the shorthand notation .field can be used in its place. For example, it.len
can be abbreviated to .len, with a leading dot. A typical use of it is to refer to each item in a list within a
loop.
for each in sys.packets{
it.len = 5;
.good = TRUE;
};

In the code above, .good is shorthand for it.good. The scope of the it variable is restricted to the for loop.
In many places it is legal to designate and use a name other than the implicit it. In the following
example, it is replaced with a variable name, p, that is declared in the iterating action.
for each (p) in sys.packets do {
print p.len;
};

See Also

Implicit Variables on page 62

1.3.3.2

me

The implicit variable me refers to the current struct and can be used anywhere in the struct. In the
following example, me refers to the current instance of the packet struct, and it refers to the current
value of tmp.
struct packet {
data: uint;
run() is also {
var tmp: uint;
gen tmp keeping {it < me.data};
print data, tmp using hex;
};
};

When referring to a field from another member of the same struct, the me. can be omitted. In the keep
constraint shown below, the name me.header.dest is equivalent to the name header.dest.
struct packet {
%header: header;

Specman e Language Reference


1999-2015

63
.

Product Version 15.1


All Rights Reserved.

keep header.dest == 0x55;


};
struct header {
%dest: int (bits: 8);
};

See Also

Implicit Variables on page 62

1.3.3.3

result

The result variable returns a value of the methods return type. If no return action is encountered, result
is returned by default. The default for the result variable is the default value for the methods return
type. The following method returns the sum of a and b:
sum(a: int, b: int): int is {
result = a + b;
};

The default result variable values for several method return types are shown below:
Method return type

Default result value

scalar types

boolean

FALSE

struct

NULL

list

empty

See Also

Implicit Variables on page 62

1.3.3.4

index

The constructs that create the implicit variable index are:

list pseudo-methods
for each
keep for each

The index variable is a non-negative integer (int) that holds the current index of the item referred to by
it. The scope of the index variable is limited to the action block.
Specman e Language Reference
1999-2015

64

Product Version 15.1


All Rights Reserved.

The following loop assigns 5 to the len field of every item in the packets list and also assigns the index
value of each item to its id field.
for each in packets do {
packets[index].len = 5;
.id = index;
};

See Also

Implicit Variables on page 62

1.3.4

Name Resolution Rules

The following sections describe how Specman resolves names, depending on whether the names include
a path or not.

Names that Include a Path on page 65

Names that Do Not Include a Path on page 66

See Also

Packages as Namespaces for Types in Creating e Testbenches

1.3.4.1

Names that Include a Path

To resolve names that include a path, Specman looks for an entity of that name at the specified scope and
issues an error message if it does not find it. In the following example, Specman is not able to resolve the
names sys.b.u or .u in the keep constraints, and issues an error if these are not commented out. It
successfully resolves all other names.
<'
struct b {
u:uint;
m() is {
print u;
};
};
struct c {
u:uint;
keep u > sys.bi.u;
keep me.u > 5;
Specman e Language Reference
1999-2015

65
.

Product Version 15.1


All Rights Reserved.

-- keep u < sys.b.u;


-- keep .u < sys.bi.u;

// 'sys' does not have a field 'b'


// no such variable 'it'

m() is {
print u;
};
};
extend sys {
bi: b;
ci: c;
run() is also {
sys.bi.m();
ci.m();
};
};
'>

Note
it.

If the path begins with a period (.), Specman assumes the path begins with the implicit variable

See Also

Names that Do Not Include a Path on page 66

1.3.4.2

Names that Do Not Include a Path

To resolve names that do not include a path, Specman performs the following checks, in order. Specman
stops after the first check that identifies the named object.
1.

Check whether the name is a macro. If there are two macro definitions, choose the most recent one.

2.

Check whether the name is one of the predefined constants. There cannot be two identical predefined
constants.

3.

Check whether the name is an enumerated type. There cannot be two identical enumerated types.

4.

Check whether the name identifies a variable used in the current action block. If not, and if the action
is nested, check whether the name identifies a variable in the enclosing action block. If not, this
search continues from the immediately enclosing action block outwards to the boundary of the
method.

5.

Check whether the name identifies a member of the current struct:

If the expression is inside a struct definition, the current struct is the enclosing struct.

Specman e Language Reference


1999-2015

66

Product Version 15.1


All Rights Reserved.

If the expression is inside a method, the current struct is the struct to which the method belongs.

6.

Check whether the name identifies a member of the global struct.

7.

If the name is still unresolved, Specman issues an error message.

Example
The following example illustrates how variables in the inner scopes hide those in the outer scopes:
m() is {
var x: int = 6;
if x > 4 then {
var x: bool = TRUE;
print x;
};
print x;
};

Result
cmd-prompt> sys.ti.m()
x = TRUE
x = 6

Note Macros, predefined constants, and enumerated types have global scope, which means they
can be seen from anywhere within an e program. For that reason, their names must be unique:

No two name macros can have the same name, and no two replacement macros can have the same
macro-namenonterminal-type (Chapter 21 Macros).
No user-defined constant can have the same name as a predefined Specman constant (Predefined
Constants on page 39).

No two enumerated types can have the same enum-type-name (Defining and Extending Scalar Types
on page 182).

See Also

Names that Include a Path on page 65

Specman e Language Reference


1999-2015

67
.

Product Version 15.1


All Rights Reserved.

1.4

Operator Precedence

The following table summarizes all e operators in order of precedence. The precedence is the same as in
the C language, with the exception of operators that do not exist in C. To change the order of
computation, place parentheses around the expression that should be computed first.
Table 1-5

Operators in Order of Precedence

Operator

Operation Type

[ ] on page 103

List indexing (subscripting)

[ .. ] on page 110

List slicing

[ : ] on page 105

Bit slicing (selection)

f(...)

Method and routine calls (see Invoking Methods and Routines on


page 49)

. on page 128

Field selection

~ on page 70,
! (not) on page 76

Bitwise not, Boolean not

{... ; ...} on page 113

List concatenation

%{... , ...} on page 115

Bit concatenation

Unary + - on page 84

Unary plus, minus

*, /, %

Binary multiply, divide, modulus (see + - * / % on page 85)

+, -

Binary add and subtract (see + - * / % on page 85)

>> << on page 74

Shift right, shift left

< <= > >= on page 87

Comparison

is [not] a on page 123

Subtype identification

== != on page 89

Equality, inequality

=== !== on page 91

Verilog four-state comparison

~ !~ on page 94

String matching

in on page 96

Inclusion/containment operator for lists and sets

&

Bitwise and (see & | ^ on page 72)

Specman e Language Reference


1999-2015

68

Product Version 15.1


All Rights Reserved.

Table 1-5

Operators in Order of Precedence, continued

Operator

Operation Type

Bitwise xor (see & | ^ on page 72)

Bitwise or (see & | ^ on page 72)

&& (and) on page 78

Boolean and

|| (or) on page 79

Boolean or

=> on page 80

Boolean implication

? : on page 131

Conditional operator (a ? b : c means if a then b else c)

Note Every operation in e is performed within the context of types and is carried out either with 32-bit
precision or unbounded precision.

See Also

Chapter 2 Data Types for information on the precision of operations and assignment rules

Evaluation Order of Expressions on page 69

1.5

Evaluation Order of Expressions

In e it is defined that and (&&) and or (||) use left-to-right lazy evaluation order (also known as short
circuit order). Consider the following statement:
bool_1 = foo(x) && bar(x)

If foo(x) returns TRUE, then bar(x) will be evaluated as well, to determine whether bool_1 gets TRUE.
If, however, foo(x) returns FALSE, then bool_1 gets FALSE immediately, and bar(x) is not executed.
The argument to bar(x) is not even evaluated.
Expressions containing || are likewise evaluated in a lazy fashion: If the subexpression on the left of the
or operator is TRUE, then the subexpression on the right is ignored.
Although e was implemented to use left-to-right evaluation for both compiled e code and interpreted e
code, that evaluation order is not required by the language definition for operators other than && or ||.
Take for example the following statement:
bool_2 = foo(x) + bar(x)

Specman e Language Reference


1999-2015

69
.

Product Version 15.1


All Rights Reserved.

If foo(x) or bar(x) has side effects (that is, if foo(x) changes the value of x or bar(x) changes the value of
x), then the results of foo(x) + bar(x) might depend on which of the two subexpressions, foo(x) or bar(x),
is evaluated first, so the results are not predictable according to the e language definition. Practically, the
left-to-right evaluation implemented in e assures predictable results, but that order is not guaranteed for
other compilers. Writing code that depends on evaluation order should be avoided.

See Also

Operator Precedence on page 68

1.6

Bitwise Operators

The following sections describe the e bitwise operators:


~ on page 70

The bitwise unary negation operator changes each 0 bit to 1 and each 1 bit
to 0 in a single expression.

& | ^ on page 72

The binary bitwise AND, OR, and XOR operators compare each bit in
one expression with the corresponding bit in a second expression to
calculate the result.

>> << on page 74

The shift-right and shift-left operators shift the bits in an expression to the
left or right a specified number of bits.

See Also

bitwise_op() on page 1484

If you are using bitwise operators in a constraint, see Understanding Semantics Used in Constraints
Versus Semantics Used in Procedural Code in Specman Generation User Guide.

1.6.1

Purpose
Unary bitwise negation

Category
Expression

Specman e Language Reference


1999-2015

70

Product Version 15.1


All Rights Reserved.

Syntax
~exp
Syntax Example
print ~x using hex;

Parameter
exp

A numeric expression or an HDL pathname.

Description
Sets each 1 bit of an expression to 0 and each 0 bits to 1. Each bit of the result expression is the opposite
of the same bit in the original expression.

Example 1
This example shows the effect of the ~ operator on a 32-bit integer.
run() is also {
var x : int = 0xff;
print ~x using hex;
};

Result
~x = 0xffffff00

Example 2
This example shows the effect of the ~ operator on a 2-bit integer.
run() is also {
var x : uint (bits:2) = 2;
print ~x using bin;
};

Result
~x = 0b01

Specman e Language Reference


1999-2015

71
.

Product Version 15.1


All Rights Reserved.

Example 3
This example shows the effect of the ~ operator on an untyped expression.
When Specman cannot determine the type and bit size of an HDL signal from the context, it
automatically casts the expression as an unsigned 32-bit integer.
run() is also {
print 'top.clk';
print ~'top.clk';
print (~'top.clk')[0:0];
};

Result
'top.clk' = 0x0
~'top.clk' = 0xffffffff
(~'top.clk')[0:0] = 0x1

See Also

If you are using the ~ operator in a constraint, see Understanding Semantics Used in Constraints
Versus Semantics Used in Procedural Code in Specman Generation User Guide.

'HDL-pathname' on page 897

Scalar Types on page 138

Untyped Expressions on page 166

1.6.2

&|^

Purpose
Binary bitwise operations

Category
Expression

Syntax
exp1 operator exp2

Specman e Language Reference


1999-2015

72

Product Version 15.1


All Rights Reserved.

Syntax Example
print (x & y);

Parameters
exp1, exp2

A numeric expression or an HDL pathname.

operator is one of the following:


&

Performs an AND operation.

Performs an OR operation.

Performs an XOR operation.

Description
Performs an AND, OR, or XOR of both operands, bit by bit.
Note

You cannot use these operators on real types.

Example 1
m() is {
var x: uint = 0xff03;
var y: uint = 0x70f6;
print (x & y);
};

Result
cmd-prompt> sys.m()
(x & y) = 0x7002

Example 2
m() is {
var x: uint = 0xff03;
'top.a' = 0x70f6;
print (x | 'top.a');
};

Specman e Language Reference


1999-2015

73
.

Product Version 15.1


All Rights Reserved.

Result
cmd-prompt> sys.m()
(x | 'top.a') = 0xfff7

Example 3
extend sys {
m() is {
var x: uint = 0xff03;
var y: uint = 0x70f6;
print (x ^ y);
};
};

Result
cmd-prompt> sys.m()
(x ^ y) = 0x8ff5

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

1.6.3

>> <<

Purpose
Shift bits left or right

Category
Expression

Syntax
exp1 operator exp2
Syntax Example
outf("%x\n", x >> 4);

Specman e Language Reference


1999-2015

74

Product Version 15.1


All Rights Reserved.

Parameters
exp1

A numeric expression or an HDL pathname.

operator is one of the following:


<<

Performs a shift-left operation.

>>

Performs a shift-right operation.

exp2

A numeric expression.

Description
Shifts each bit of the first expression to the right or to the left the number of bits specified by the second
expression.
In a shift-right operation, the shifted bits on the right are lost, while on the left they are filled with 1, if
the first expression is a negative integer, or 0, in all other cases.
In a shift-left operation, the shifted bits on the left are lost, while on the right they are filled with 0.
The result of a shift by more than 31 bits is undefined in e.Therefore, only the five least significant bits
of the second expressions value are used. For example, if the second expression is 32, the operation
becomes shift-left 0. Likewise, if the second expression is 33, the operation becomes shift-left 1, and so
on.
Note

You cannot use these operators with real data types.

Example 4
m() is {
var x: int = 0x8fff0011;
outf("%x\n", x >> 4);
var y: uint = 0x8fff0011;
outf("%b\n", y >> 4);
};

Result
cmd-prompt> sys.m()
f8fff001
1000111111111111000000000001

Specman e Language Reference


1999-2015

75
.

Product Version 15.1


All Rights Reserved.

Example 5
m() is {
'top.a' = 0x8fff0011;
outf("%x\n", 'top.a' << 4);
};

Result
cmd-prompt> sys.m()
fff00110

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

1.7

Boolean Operators

The following sections describe the e Boolean operators:


! (not) on page 76

Returns TRUE when an expression evaluates to FALSE, and vice versa.

&& (and) on page 78

Returns TRUE if two expressions are both TRUE.

|| (or) on page 79

Returns TRUE if one of two expressions is TRUE.

=> on page 80

Returns TRUE when the first expression of two expressions is FALSE,


or when both expressions are TRUE.

now on page 81

Returns TRUE if an event has occurred in the current cycle.

1.7.1

! (not)

Purpose
Boolean not operation

Category
Expression

Specman e Language Reference


1999-2015

76

Product Version 15.1


All Rights Reserved.

Syntax
!exp
not exp
Syntax Example
out(!(3 > 2));

Parameters
exp

A Boolean expression or an HDL pathname.

Description
Returns FALSE when the expression evaluates to TRUE and returns TRUE when the expression
evaluates to FALSE.

Example
m() is {
'top.a' = 3;
out(!('top.a' > 2));
out(not FALSE);
};

Result
cmd-prompt> sys.m()
FALSE
TRUE

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

Specman e Language Reference


1999-2015

77
.

Product Version 15.1


All Rights Reserved.

1.7.2

&& (and)

Purpose
Boolean and

Category
Expression

Syntax
exp1 && exp2
exp1 and exp2
Syntax Example
if (2 > 1) and (3 > 2) then {
out("3 > 2 > 1");
};

Parameters
exp1, exp2

A Boolean expression or an HDL pathname.

Description
Returns TRUE if both expressions evaluate to TRUE; otherwise, returns FALSE.

Example
m() is {
'top.a' = 3;
'top.b' = 2;
if ('top.b' > 1) and ('top.a' > 'top.b') then {
out("'top.a' > 'top.b' > 1");
};
};

Specman e Language Reference


1999-2015

78

Product Version 15.1


All Rights Reserved.

Result
cmd-prompt> sys.m()
'top.a' > 'top.b' > 1

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

1.7.3

|| (or)

Purpose
Boolean or

Category
Expression

Syntax
exp1 || exp2
exp1 or exp2
Syntax Example
if FALSE || ('top.a' > 1) then {
out("'top.a' > 1");
};

Parameters
exp1, exp2

A Boolean expression or an HDL pathname.

Description
Returns TRUE if one or both expressions evaluate to TRUE; otherwise, returns FALSE.

Specman e Language Reference


1999-2015

79
.

Product Version 15.1


All Rights Reserved.

Example
m() is {
'top.a' = 3;
if FALSE || ('top.a' > 1) then {
out("'top.a' > 1");
};
};

Result
cmd-prompt> sys.m()
'top.a' > 1

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

1.7.4

=>

Purpose
Boolean implication

Category
Expression

Syntax
exp1 => exp2
Syntax Example
out((2 > 1) => (3 > 2));

Parameters
exp1, exp2

A Boolean expression.

Specman e Language Reference


1999-2015

80

Product Version 15.1


All Rights Reserved.

Description
The expression returns TRUE when the first expression is FALSE, or when the second expression is
TRUE. This construct is the same as:
(not exp1) or (exp2)

Example
m() is {
out((2 > 1) => (3 > 2));
out((1 > 2) => (3 > 2));
out((2 > 1) => (2 > 3));
};

Result
cmd-prompt> sys.m()
TRUE
TRUE
FALSE

See Also

Understanding Real Number Generation in the Specman Generation User Guide

Scalar Types on page 138

1.7.5

now

Purpose
Boolean event check

Category
Boolean expression

Syntax
now @event-name

Specman e Language Reference


1999-2015

81
.

Product Version 15.1


All Rights Reserved.

Syntax Example
if now @sys.tx_set then {
out("sys.tx_set occurred");
};

Parameter
event-name The event to be checked.

Description
Evaluates to TRUE if the event occurs before the now expression is encountered, in the same cycle in
which the now expression is encountered.
However, if the event is consumed later during the same cycle, the now expression changes to FALSE.
This means that the event can be missed, if it succeeds after the expression is encountered.

Example 1
In the following, the sys.tx_set event is checked when the if action is encountered. If the sys.tx_set event
has already occurred, in the same sys.clk cycle, the out() routine is called.
struct pkt {
event clk is @sys.any;
tcm_exa()@clk is {
if now @sys.tx_set then {
out("sys.tx_set occurred");
};
};
run() is also {
start tcm_exa();
};
};

Example 2
In this example, the now expression is FALSE until the tx_set event is emitted, which changes the
expression to TRUE. When the event is consumed by sync consume (@tx_set), the now expression
changes back to FALSE.
struct pkt {
event tx_set;
tcm_exa()@sys.any is {
Specman e Language Reference
1999-2015

82

Product Version 15.1


All Rights Reserved.

print now @tx_set;


emit tx_set;
print now @tx_set;
sync consume (@tx_set);
print now @tx_set;
};
run() is also {
start tcm_exa();
};
};
extend sys {
p_i: pkt;
};

Example 3
In this example, it is guaranteed that both now expressions evaluate to TRUE only if the events are
emitted in the same tick. The order of the evaluation is the same as the order of the now expressions in
the e code.
extend sys {
event ck is @any;
event a is true('a'==1) @ck;
event b is true('b'==1) @ck;
tcm() @ck is {
wait @a or @b;
if now @a then {
print 'a';
};
if now @b then {
print 'b';
};
};
};

See Also

Chapter 12 Events

Scalar Types on page 138

Specman e Language Reference


1999-2015

83
.

Product Version 15.1


All Rights Reserved.

1.8

Arithmetic Operators

The following sections describe the e arithmetic operators:


Unary + - on page 84

Perform arithmetic operations on a single operand.

+ - * / % on page 85

Perform arithmetic operations on two operands.

1.8.1

Unary + -

Purpose
Unary plus and minus

Category
Expression

Syntax
-exp
+exp
Syntax Example
out(5," == ", +5);

Parameter
exp

A numeric expression or an HDL pathname.

Description
Performs a unary plus or minus of the expression. The minus operation changes a positive integer to a
negative one, and a negative integer to a positive one. The plus operation leaves the expression
unchanged.

Example 1
m() is {
out(5," == ", +5);
Specman e Language Reference
1999-2015

84

Product Version 15.1


All Rights Reserved.

};

Result
cmd-prompt> sys.m()
5 == 5

Example 2
m() is {
var x: int = 3;
print -x;
print -(-x);
};

Result
cmd-prompt> sys.m()
-x = -3
-(-x) = 3

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

1.8.2

+-*/%

Purpose
Binary arithmetic

Category
Expression

Syntax
exp1 operator exp2

Specman e Language Reference


1999-2015

85
.

Product Version 15.1


All Rights Reserved.

Syntax Example
out(10 + 5);

Parameters
exp1, exp2

A numeric expression or an HDL pathname.

operator is one of the following:


+

Performs addition.

Performs subtraction.

Performs multiplication.

Performs division and returns the quotient, rounded down.

Performs division and returns the remainder.

Description
Performs binary arithmetic operations.
Note

You cannot use the % operator on real types.

Example 1
m() is {
out(4 * -5);
};

Result
cmd-prompt> sys.m()
-20

Example 2
m() is {
out(21 / 7);
out(27 / 7);
};

Specman e Language Reference


1999-2015

86

Product Version 15.1


All Rights Reserved.

Result
cmd-prompt> sys.m()
3
3

Example 3
m() is {
out(23 % 7);
};

Result
cmd-prompt> sys.m()
2

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

Arithmetic Routines on page 1469

1.9

Comparison Operators

The following sections describe the e comparison operators:


< <= > >= on page 87

Compares two numeric expressions or HDL pathnames.

== != on page 89

Determines whether two expressions are equal or not.

=== !== on page 91

Performs a 4-state, Verilog-style comparison of HDL objects.

~ !~ on page 94

Determines whether two string expressions are equal or not.

in on page 96

Determines whether an expression is in a list or a range.

1.9.1

< <= > >=

Purpose
Comparison of values

Specman e Language Reference


1999-2015

87
.

Product Version 15.1


All Rights Reserved.

Category
Expression

Syntax
exp1 operator exp2
Syntax Example
print 'top.a' >= 2;

Parameters
exp1, exp2

A numeric expression, or an HDL pathname.

operator is one of the following:


<

Returns TRUE if the first expression is smaller than the second expression.

<=

Returns TRUE if the first expression is not larger than the second expression.

>

Returns TRUE if the first expression is larger than the second expression.

>=

Returns TRUE if the first expression is not smaller than the second expression.

Description
Compares two expressions.

Example
m() is {
'top.a' = 3;
print 'top.a' >= 2;
};

Result
cmd-prompt> sys.m()
'top.a' >= 2 = TRUE

Specman e Language Reference


1999-2015

88

Product Version 15.1


All Rights Reserved.

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

1.9.2

== !=

Purpose
Equality of values

Category
Expression

Syntax
exp1 operator exp2
Syntax Example
print lob1 == lob2;
print p1 != p2;

Parameters
exp1, exp2

Any e expression.

operator is one of the following


==

Returns TRUE if the first expression evaluates to the same value as the second expression.

!=

Returns TRUE if the first expression does not evaluate to the same value as the second
expression.

Description
The equality operators compare the items and return a Boolean result. All types of items are compared
by value, except for structs which are compared by address. Comparison methods for the various data
types are listed in Table 1-6.

Specman e Language Reference


1999-2015

89
.

Product Version 15.1


All Rights Reserved.

Table 1-6

Equality Comparisons for Various Data Types

Type

Comparison Method

integers, unsigned integers,


Boolean values, HDL pathnames

Values are compared.

strings

The strings are compared character by character.

sets

The sets are compared value by value. Two integer sets are equal
if and only if every value in one set exists in the other set.

lists

The lists are compared item by item.


See also List Equality and Inequality in Specman Generation
User Guide.

structs

The structs addresses are compared.


See also Struct Equality and Struct Assignment in
Constraining Struct Instances in Specman Generation User

Guide.

Notes

Enumerated type values can be compared as long as they are of the same type.
Do not use these operators to compare a string to a regular expression. Use the ~ or the !~ operator
instead.
See === !== on page 91 for a description of using this operator with HDL pathnames.

Example
extend sys {
p1: packet;
p2: packet;
m() is {
var s: string = "/rtests/tmp";
var b: bool = TRUE;
var lob1: list of byte = {0xaa; 0xbb; 0xcc; 0xdd};
var lob2: list of byte = lob1;
print
print
print
print

s == "/rtests/tmp";
b != FALSE;
lob1 == lob2;
p1 != p2;

Specman e Language Reference


1999-2015

90

Product Version 15.1


All Rights Reserved.

};
};

Result
cmd-prompt> sys.m()
s == "/rtests/tmp" = TRUE
b != FALSE = TRUE
lob1 == lob2 = TRUE
p1 != p2 = TRUE

See Also

=== !== on page 91

~ !~ on page 94

'HDL-pathname' on page 897

Scalar Types on page 138

1.9.3

=== !==

Purpose
Verilog-style four-state comparison operators

Category
Expression

Syntax
'HDL-pathname' [!== | ===] exp
exp [!== | ===] 'HDL-pathname'
Syntax Example
print 'TOP.reg_a' === 4'b1100;

Specman e Language Reference


1999-2015

91
.

Product Version 15.1


All Rights Reserved.

Parameters
HDL-pathname

The full path name of an HDL object, optionally including expressions and
composite data. See 'HDL-pathname' on page 897 for more information.

===

Determines identity, as in Verilog. Returns TRUE if the left and right operands
have identical values, considering also the x and z values.

!==

Determines non-identity, as in Verilog. TRUE if the left and right operands differ
in at least 1 bit, considering also the x and z values.

==

Returns TRUE if after translating all x values to 0 and all z values to 1, the left
and right operands are equal.

!=

Returns TRUE if after translating all x values to 0 and all z values to 1, the left
and right operands are non-equal.

exp

Either a literal with four-state values, a numeric expression, or another HDL


pathname.

Description
Compares four-state values (0, 1, x and z) with the identity and non-identity operators (Verilog style
operators). Alternatively, you can use the regular equal and non-equal operators. (A description of the
regular identity and non-identity operators is included in Parameters on page 92, for clarity.)
There are three ways to use the identity (===) and non-identity (!==) operators:

'HDL-pathname' = = = literal-number-with-x-and-z values


This expression compares a HDL object to a literal number (for example 'top.reg' === 4'b11z0). It
checks that the bits of the HDL object match the literal number, bit by bit (considering all four
values 0, 1, x, z).

'HDL-pathname' = = = number-exp
This expression evaluates to TRUE if the HDL object is identical in each bit value to the integer
expression number-exp. Integer expressions in e cannot hold x and z values; thus the whole
expression can be true only if the HDL object has no x or z bits and is otherwise equal to the integer
expression.

'HDL-pathname' = = = 'second-HDL-pathname'
This expression evaluates to TRUE if the two HDL objects are identical in all their bits (considering
all four values 0, 1, x, z).

Specman e Language Reference


1999-2015

92

Product Version 15.1


All Rights Reserved.

Example 1
In Specman as in Verilog, if the radix is not binary, the z and x values in a literal number are interpreted
as more than one bit wide and are left-extended when they are the left-most literal. The width they
assume depends on the radix. For example, in hexadecimal radix, each literal z counts as four z bits.
Thus the value assigned in the following statement is 20'bxxxx_xxxx_zzzz_0000_0001.
'x.signal[19:0]' = 20'hxz01;

Because z is evaluated as 1 and x as 0 in ordinary expressions, the value printed by the following
statement is 0000_0000_1111_0000_0001.
print 'x.signal';

Because x is evaluated as 1 and other values as 0 in expressions with @x, the value printed by the
following statement is 1111_1111_0000_0000_0000.
print 'x.signal@x';

Because z is evaluated as 1 and other values as 0 in expressions with @z, the value printed by the
following statement is 0000_0000_1111_0000_0000.
print 'x.signal@z';

Example 2
In the following example, both comparisons evaluate to TRUE.
'TOP.reg_a' = 4'b1100;
wait cycle;
print 'TOP.reg_a' === 4'b1100;
print 'TOP.reg_a' === 0xC;

Example 3
This example shows how to test a single bit to determine its current state.
case {
'TOP.write_en' === 1'b0: {
out("write_en is 0");
};
'TOP.write_en' === 1'b1: {
out("write_en is 1");
Specman e Language Reference
1999-2015

93
.

Product Version 15.1


All Rights Reserved.

};
'TOP.write_en' === 1'bx: {
out("write_en is x");
};
'TOP.write_en' === 1'bz: {
out("write_en is z");
};
};

See Also

'HDL-pathname' on page 897

Scalar Types on page 138

1.9.4

~ !~

Purpose
String matching

Category
Expression

Syntax
string operator pattern-string
Syntax Example
print s ~ "blue*";
print s !~ "/^Bl.*d$/";

Parameters
string

A legal e string.

operator is one of the following:


~

Returns TRUE if the pattern string can be matched to the whole string.

Specman e Language Reference


1999-2015

94

Product Version 15.1


All Rights Reserved.

!~

Returns TRUE if the pattern string cannot be matched to the whole string.

pattern-string

Either an AWK-style regular expression or a native Specman regular expression. If


the pattern string starts and ends with slashes, then everything inside the slashes is
treated as an AWK-style regular expression. See String Matching on page 99 for
more information.

Description
Matches a string against a pattern. There are two styles of string matching: native Specman style, which
is the default, and AWK-style.
After a successful match, you can use the local pseudo-variable $0 to retrieve the entire matched string.
The variables $1, $2...$30 hold portions of the matched string (the submatches), either:

The portions of a native Specman regular expression that correspond to the asterisk or ellipsis
characters present in the match pattern.
The portions of an AWK-style regular expression that correspond to characters enclosed in
parentheses in the match pattern.

Example 1
The first two patterns use Specman style; the next two use AWK.
m() is {
var s: string = "BlueBird";
print
print
print
print

s
s
s
s

~
~
~
~

"Blue*";
"blue*";
"/^Bl.*d$/";
"/^bl.*d$/";

};

Result
cmd-prompt> sys.m()
s ~ "Blue*" = TRUE
s ~ "blue*" = TRUE
s ~ "/^Bl.*d$/" = TRUE
s ~ "/^bl.*d$/" = FALSE

Specman e Language Reference


1999-2015

95
.

Product Version 15.1


All Rights Reserved.

Example 2
The first pattern uses Specman style; the next uses AWK.
m() is {
var s: string = "BlueBird";
print s !~ "blue*";
print s !~ "/^Bl.*d$/";
};

Result
cmd-prompt> sys.m()
s !~ "blue*" = FALSE
s !~ "/^Bl.*d$/" = FALSE

See Also

The string Type on page 158

1.9.5

in

Purpose
Check whether a value is included in a list or set or whether one list or set is contained in a second list or
set.

Category
Expression

Syntax
exp1 in exp2 :bool
Syntax Example
keep x in [1..5];
assert x in {1;2;3;4;5};

Specman e Language Reference


1999-2015

96

Product Version 15.1


All Rights Reserved.

Parameters
.

exp1

Valid e expression. The value(s) represented by exp1 of must match the type of of the
value(s) represented by exp2.

exp2

Any list or set expression.


When exp2 is a collection of elements:

Curly braces are used for list elements.


Square braces are used for set elements.

Description
Returns TRUE if the expression on the left-hand side is a member of or included in the expression on the
right-hand side.
Note When set expressions are used in constraints, they must be inputs only (they cannot be
generative). The following example illustrates correct and incorrect usage:
!s: set;
x: uint;
keep x in value(s) \\ Correct usage.
keep x in s
\\ Incorrect usage. Results in an error.

Example 1
This example checks to make sure that a variable is generated correctly by confirming that its value is in
a list of values.
extend sys {
x: int (bits: 64);
keep x in [1..5];
run() is also {
assert x in {1;2;3;4;5};
};
};

Example 2
This example illustrates the use of in with a set of enumerated values, to designate a range of values for
a constraint.
type pm_type: [PC_A, PC_B, PC_C, MM_A, MM_B];
extend sys {
Specman e Language Reference
1999-2015

97
.

Product Version 15.1


All Rights Reserved.

pm: pm_type;
keep pm in [PC_A, PC_B, PC_C];
};

Example 3
When two lists are compared and the first one has more than one repetition of the same value (for
example, in {1;2;1}, 1 is repeated twice), then at least the same number of repetitions has to exist in the
second list for the operator to succeed.
In this example, the list y is constrained to have 0 or 2 elements. The first check makes sure that y
contains 0 to 2 instances of the numbers 0, 1, 2, and 3. An error is issued for the second check.
<'
extend sys {
y: list of uint (bits: 2);
keep y.size() in {0;2};
run() is also {
assert y in {0;0;1;1;2;2;3;3};
assert {1;1;2} in {1;2;3;4};
};
};
'>

Result
cmd-prompt> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
*** Error: Assertion failed (a programming error);
assert {1;1;2} in {1;2;3;4}
In sys.run() at line 8 in in_example.e

Example 4
This example illustrates that the order of the list items does not influence the result of the comparison.
No error is issued.
<'
extend sys {
run() is also {
assert {1;2;3} in {3;2;1};
Specman e Language Reference
1999-2015

98

Product Version 15.1


All Rights Reserved.

assert {1;1;2} in {1;2;1;2};


};
};
'>

See Also

List Types on page 155

The set Type on page 142

Using Sets in Constraints in the Specman Generation User Guide

1.10 String Matching


There are two styles of string matching: native Specman style, which is the default, and an AWK-like
style. If the pattern starts and ends with slashes, then everything inside the slashes is treated as an
AWK-style regular expression.
The following sections describe these two styles of string matching:

Native Specman String Matching on page 99

AWK-Style String Matching on page 101

See Also

List Types on page 155

String Routines on page 1487

1.10.1

Native Specman String Matching

Specman string matching is attempted on all match patterns that are not enclosed in slashes. Specman
style is similar to UNIX filename matching.
Table 1-7 shows the meta-characters you can use in native Specman string match patterns.

Table 1-7

Meta-Characters in Native String Match Patterns

Character String

Meaning

" " (blank)

Any sequence of white space (blanks and tabs)

* (asterisk)

Any sequence of non-white space characters, possibly empty


(""). "a*" matches "a", "ab", and "abc", but not "ab c".

Specman e Language Reference


1999-2015

99
.

Product Version 15.1


All Rights Reserved.

Table 1-7

Meta-Characters in Native String Match Patterns

Character String

Meaning

... (ellipsis)

Any sequence of characters

Native string matching always matches the full string to the pattern. For example: r does not match
Bluebird, but *r* does.
A successful match results in assigning the local pseudo-variable $0 with the entire matched string. The
variables $1 to $30 are assigned with the portions of the matched string that correspond to the asterisk or
ellipsis characters present in the pattern. These partial strings are called submatches.
Notes

The pseudo-variables are set by str_match() or the ~ operator and are local to the method that calls
this routine or uses this operator. If fewer than 31 substrings are created, then the unneeded variables
are left empty.
The maximum number of allowed submatches in a regular expression used in string matching is 50.
As a result, the submatches between 31 and 50 can be created, but cannot be accessed with a local
pseudo-variable.
Native style string matching is case-insensitive.

Example
m() is {
var x
print
print
print
print
};

:= "pp kkk";
x ~ "* *";
$1; print $2;
x ~ "...";
$1;

Result
cmd-prompt> sys.m()
x ~ "* *" = TRUE
$1 = "pp"
$2 = "kkk"
x ~ "..." = TRUE
$1 = "pp kkk"

Specman e Language Reference


1999-2015

100

Product Version 15.1


All Rights Reserved.

See Also

AWK-Style String Matching on page 101

The string Type on page 158

String Routines on page 1487

1.10.2

AWK-Style String Matching

In an AWK-style string matching you can use the standard AWK regular expression notation to write
complex patterns. This notation uses the /.../ format for the pattern to specify AWK-style regular
expression syntax.
AWK style supports special characters such as . * [ \ ^ $ +? <>, when those characters are used in the
same ways as in UNIX regular expressions (regexp).
The + and ? characters can be used in the same ways as in UNIX extended regular expression (egrep).
In AWK-style regular expressions, you can also use the following Perl shorthand notations, each
representing a single character.
Table 1-8

Perl-Style Regular Expressions Supported

Shorthand Notation

Meaning

A shortest match operator: ` (back tick).

\d

Digit: [0-9]

\D

Non-digit

\s

Any white-space single char

\S

Any non-white-space single

\w

Word char: [a-zA-Z0-9_]

\W

Non-word char

A successful match results in assigning the local pseudo-variable $0 with the entire matched string. The
variables $1 to $30 are assigned with the portions of the matched string that correspond to characters
enclosed in parentheses in the pattern. These partial strings are called submatches.
Notes

The pseudo-variables are set by str_match() or the ~ operator and are local to the method that calls
this routine or uses this operator. If fewer than 31 substrings are created, then the unneeded variables
are left empty.

Specman e Language Reference


1999-2015

101
.

Product Version 15.1


All Rights Reserved.

The maximum number of allowed submatches in a regular expression used in string matching is 50.
As a result, the submatches between 31 and 50 can be created, but cannot be accessed with a local
pseudo-variable.

Example 1
m() is {
var x := "pp--kkk";
print (x ~ "/--/");
print (x ~ "/^pp--kkk$/");
};

Result
cmd-prompt> sys.m()
x ~ "/--/" = TRUE
x ~ "/^pp--kkk$/" = TRUE

Example 2
AWK-style matching is longest match. Specman supports also a shortest match operator: ` (back tick).
The pattern /x.`y/ matches the minimal such substring.
m() is {
var s
print
print
print
print
};

:= "x x y y";
s ~ "/x(.)y/";
$1;
s ~ "/x(.*)y/";
$1;

//
//
//
//

Prints
Prints
Prints
Prints

TRUE
" x ". Matches x x y
TRUE
" x y. "Matches x x y y

Result
cmd-prompt> sys.m()
s ~ "/x(.)y/" = TRUE
$1 = " x "
s ~ "/x(.*)y/" = TRUE
$1 = " x y "

Example 3
After doing a match, you can use the local pseudo-variables $1, $2...$30, which correspond to the
parenthesized pieces of the match. For instance:

Specman e Language Reference


1999-2015

102

Product Version 15.1


All Rights Reserved.

m() is {
var x := "pp--kkk";
if x ~ "/^(p*)--(k*)$/" then {print $1, $2;};
};

Result
cmd-prompt> sys.m()
$1 = "pp"
$2 = "kkk"

See Also

Native Specman String Matching on page 99

The string Type on page 158

String Routines on page 1487

1.11 Extraction and Concatenation Operators


The following sections describe the e extraction and concatenation operators:
[ ] on page 103

Extracts or sets a single item from a list.

[ : ] on page 105

Extracts or sets consecutive bits or slices of a scalar, a list of bits, or


a list of bytes.

[ .. ] on page 110

List slicing operator

[ range,...] on page 119

Set literal operator

{... ; ...} on page 113

List concatenation

%{... , ...} on page 115

Bit concatenation

1.11.1

[]

Purpose
List index operator

Category
Expression
Specman e Language Reference
1999-2015

103
.

Product Version 15.1


All Rights Reserved.

Syntax
list-exp[exp]
Syntax Example
ints[size] = 8;

Parameters
list-exp

An expression that returns a list.

exp

A numeric expression.

Description
Extracts or sets an indexed item from a list. For multi-dimensional lists, the item, itself, might also be a
list.

Notes

Indexing is only allowed for lists. To get a single bit from a scalar, use bit extraction. See [ : ] on
page 105.
Checking list boundaries to see if the specified element exists is done only in interpretive mode.

Example 1

One-Dimensional List Indexing

<'
extend sys {
packets[7]: list of packet;
ints[15]: list of int;
size: int [0..15];
m() is {
print packets[5];
ints[size] = 8;
print ints[size];
};
};
'>

Result
cmd-prompt> sys.m()
Specman e Language Reference
1999-2015

104

Product Version 15.1


All Rights Reserved.

packets[5] = packet-@0: packet


---------------------------------------------0
protocol:
atm
1
len:
1
2
data:
(1 items)
ints[size] = 8

Example 2

@basics69

Multi-Dimensional List Indexing

extend sys {
!matrix[4][4]: list of list of int;
run() is also {
for i from 0 to 3 {
for j from 0 to 3 {
matrix[i][j] = i * j;
};
};
assert matrix[1] == {1 * 0; 1 * 1; 1 * 2 ; 1 * 3};
// Override item #0 and resize it to 3
matrix[0] = {9; 99; 999};
print matrix;
};
};

See Also

List Types on page 155

Chapter 25 List Pseudo-Methods

1.11.2

[:]

Purpose
Select bits or bit slices of an expression

Category
Expression

Specman e Language Reference


1999-2015

105
.

Product Version 15.1


All Rights Reserved.

Syntax
exp[[high-exp]:[low-exp][:slice]]
Syntax Example
print u[15:0] using hex;

Parameters
exp

A numeric expression, an HDL pathname, or an expression returning a list of bit or a


list of byte.

high-exp

A non-negative numeric expression. The high expression has to be greater than or


equal to the low expression. To extract a single slice, use the same expression for both
the high expression and the low expression.

low-exp

A non-negative numeric expression, less than or equal to the high expression.

slice

A numeric expression. The default is bit.

Description
Extracts or sets consecutive bits or slices of a scalar, a list of bits, or a list of bytes.
When used on the left-hand-side of an assignment operator, the bit extract operator sets the specified bits
of a scalar, a list of bits, or a list of bytes to the value on the right-hand-side (RHS) of the operator. The
RHS value is chopped or zero/sign extended, if needed.
When used in any context except the left-hand-side of an assignment operator, the bit extract operator
extracts the specified bits of a scalar, a list of bits, or a list of bytes.

Slice and Size of the Result


The slice parameter affects the size of the slice that is set or extracted. With the default slice (bit), the bit
extract operator always operates on a 1-bit slice of the expression. When extracting from a scalar
expression, by default the bit extract operator returns an expression that is the same type and size as the
scalar expression. When extracting from a list of bit or a list of byte, by default the result is a positive
unbounded integer.
By specifying a different slice (byte, int, or uint), you can cause the bit operator to operate on a larger
number of bits.
For example, the first print statement displays the lower two bytes of big_i, 4096. The second print
statement displays the higher 32-bit slice of big_i, -61440.
Specman e Language Reference
1999-2015

106

Product Version 15.1


All Rights Reserved.

var big_i: int (bits: 64) = 0xffff1000ffff1000;


print big_i[1:0:byte];
print big_i[1:1:int];

Result
big_i[1:0:byte] = 0x0000000000001000
big_i[1:1:int] = 0xffffffffffff1000

Accessing Nonexistent Bits


If the expression is a numeric expression or an HDL pathname, any reference to a non-existent bit is an
error. However, for unbounded integers, all bits logically exist and will be 0 for positive numbers, 1 for
negative numbers. It is an error to extract nonexisting bits from list items. When setting non-existing bits
in list items, new zero items are added.

Notes

The [high : low] order of the bit extract operator is the opposite of [low.. high] order of the list extract
operator.
The bit extract operator has a special behavior in packing. Packing the result of a bit extraction uses
the exact size in bits (high - low + 1). The size of this pack expression is (5 - 3 + 1) + (i - 3 + 1).
pack(packing.low, A[5:3], B[i:3]);

Example 1
This is a simple example showing how to extract and set the bits in an unsigned integer.
var x : uint = 0x8000_0a60;
print x[11:4];
print x[31:31];
x[3:0] = 0x7;
print x;
x[2:1:byte] = 0x1234;
print x;

Result
x[11:4] = 0xa6
x[31:31] = 0x1
x = 0x80000a67
x = 0x80123467
Specman e Language Reference
1999-2015

107
.

Product Version 15.1


All Rights Reserved.

Example 2
This example shows how to extract and set the bits in a list of bit.
var y : list of bit = {0;1;0;1;1;0;1;0;0;0;0};
print y using bin;
print y[6:1] using bin;
y[6:1] = 0xff;
print y using bin;
var x : uint = y[:];
print x using hex;

Result
y =

(11 items, bin):


0 0 0

0 1 0 1

1 0 1 0

.0

0 0 0

0 1 1 1

1 1 1 0

.0

y[6:1] = 0b101101
y = (11 items, bin):

x = 0x7e

Example 3
This example shows how to extract and set the bits in a list of byte.
var z : list of byte = {0x12;0x34;0x56};
print z;
print z[1:0];
print z[1:0:byte];
z[2:2:byte] = 0x48;
print z;

Result
z =

(3 items, hex):
56 34 12

.0

48 34 12

.0

z[1:0] = 0x2
z[1:0:byte] = 0x3412
z = (3 items, hex):

Specman e Language Reference


1999-2015

108

Product Version 15.1


All Rights Reserved.

Example 4
This example shows how to use variables in the bit extract operator.
var x
var i
var j
print

: uint = 0x80065000;
: uint = 16;
: uint = 4;
x[i+j:i-j] using hex;

Result
x[i+j:i-j] = 0x65

Example 5
This example shows how to use variables in the bit extract operator. r will be an unbounded integer
containing 32 bits, extracted starting from byte 1 of the list of bit.
var lob : list of bit;
gen lob keeping {.size() < 128};
print lob;
var i : uint = 1;
var r:= lob[i+3:i:byte];
print r using bin;

Result
lob =

(40 items, hex):


1 0 1 1 1 0 0 1

0 1 1 1
1 0 1 0

1 0 1 1
0 1 0 1

1 0 0 0
1 0 0 1

0 0 0 1
1 1 0 0

.0
.24

r = 0b0000000010100101100111001011100101111011

See Also

Bit Slice Operator and Packing on page 1056

'HDL-pathname' on page 897

List Types on page 155

Scalar Types on page 138

Specman e Language Reference


1999-2015

109
.

Product Version 15.1


All Rights Reserved.

1.11.3

[ .. ]

Purpose
List slicing operator

Category
Expression

Syntax
exp[[low-exp]..[high-exp]]
Syntax Example
print ints[0..size];

Parameters
exp

An expression returning a list or a scalar.

low-exp

An expression evaluating to a positive integer. The default is 0.

high-exp

An expression evaluating to a positive integer. The default is the expression size on bits - 1.

Description
Accesses the specified list items and returns a list of the same type as the expression. If the expression is
a list of bit it returns a list of bit. If the expression is a scalar, it is implicitly converted to a list of bit.
The rules for the list slicing operator are as follows:

A list slice of the form a[m..n] requires that n>=m>=0 and n<a.size(). The size of the slice in this
case is always n-m+1.
A list slice of the form a[m..] requires that m>=0 and m<=a.size(). The size of the slice in this case
is always a.size()-m.
When assigning to a slice the size of the rhs must be the same as the size of the slice, specifically
when the slice is of form a[m..] and m==a.size() then the rhs must be an empty list.

These rules are also true for the case of list slicing a numeric value, for example
var i:int;
Specman e Language Reference
1999-2015

110

Product Version 15.1


All Rights Reserved.

print i[m..n];
print i[m..];

This operator interprets the numeric value as a list of bits and returns the slice of that list. In the above
example, the first print is legal if n>=m>=0 and n<32 and the second is legal if m>=0 and m<=32.

Note

This operator is not supported for unbounded integers.


The only case where a list slice operation returns an empty list is in the case of a[m..] where
m==a.size().

Example 1

List Slicing for a One-Dimensional List

This example shows the use of the list slicing operator on a list of integers and a list of structs.
<'
struct packet {
protocol:[atm, eth];
len : int [0..10];
data[len]: list of byte;
};
extend sys {
packets[7]: list of packet;
ints[15]: list of int;
size: int [0..15];
run() is also {
print packets[5..];
print ints[0..size];
};
};
'>

Result
packets[5..] =
item
type
protocol
len
data
--------------------------------------------------------------0.
packet
atm
1
(1 items)
1.
packet
eth
5
(5 items)
ints[0..size] =
0.
2030699911
1.
-419930323
2.
-1597130501
3.
-494877665
Specman e Language Reference
1999-2015

111
.

Product Version 15.1


All Rights Reserved.

4.
5.
6.
7.
8.
9.

-17370926
-1450077749
1428017017
2036356410
-1952412155
-259249691

Example 2

List Slicing for a Multi-Dimensional List

This example shows the use of the list slicing operator on a multi-dimensional list.
extend sys {
run() is also {
var l_3dim: list of list of list of int = \
{ {{1;2};{3}}; {{4};{5}};{{6;7};{7;8}};{{9};{0}}};
var l_3dim_other: list of list of list of int = l_3dim[1..];
assert l_3dim_other.size() == 3;
assert l_3dim_other[0] == l_3dim[0];
assert l_3dim_other[1] == l_3dim[2];
assert l_3dim_other[2] == l_3dim[3];
};
};

Example 3
This example shows the use of the list slicing operator on a scalar expression and an HDL pathname.
<'
extend sys {
run() is also {
var u : uint = 0xffffaaaa;
print u[..15];
'top.a' = 0xbbbbcccc;
print 'top.a'[..15];
};
};
'>

Result
u[..15] =

(16 items, hex):

'top.a'[..15] =

a a a a

.0

c c c c

.0

(16 items, hex):

Specman e Language Reference


1999-2015

112

Product Version 15.1


All Rights Reserved.

See Also

'HDL-pathname' on page 897

List Types on page 155

Scalar Types on page 138

1.11.4

{... ; ...}

Purpose
List concatenation

Syntax
{exp; ...}
Syntax Example
var x: list of uint = {1;2;3};

Category
Expression

Parameters
exp

Any legal e expression, including a list. All expressions need to be


compatible with the result type.

Description
Returns a list built out of one or more elements or other lists. The result type is determined by the
following rules:

The type is derived from the context. In the following example, the result type is a list of uint:
var x: list of uint = {1;2;3};

When the context is not defined, the type is derived from the first element type of the list. In the
following example, the result type is a list of int 50 bits wide:
var y := {50'1; 2; 3};

Specman e Language Reference


1999-2015

113
.

Product Version 15.1


All Rights Reserved.

Note The type for a sub-list in a multi-dimensional list can be the list type or the element type,
depending on the context. When the context is not defined, the list gets the type of the first element item.
For example, in the following code:
var matrix: list of list of int = { {1;2;3} ; {4;5;6}};
print {{1;2;3}} in matrix;

The {{1;2;3}} type is list of int and not list of list of int.

Example
<'
type color:[red, orange, yellow, green, blue, purple];
extend sys {
run() is also {
var los: list of string = {"abc";"def"};
var loc1: list of color = {red;green;blue};
var loc2:={color'purple;loc1};
print los;
print loc1;
print loc2;
};
};
'>

Result
los =
0.
"abc"
1.
"def"
loc1 =
0.
red
1.
green
2.
blue
loc2 =
0.
purple
1.
red
2.
green
3.
blue

See Also

List Types on page 155

Specman e Language Reference


1999-2015

114

Product Version 15.1


All Rights Reserved.

1.11.5

%{... , ...}

Purpose
Bit concatenation operator

Category
Expression

Syntax
%{expr, ...}
Syntax Example
num1 = %{num2, num3};
%{num2, num3} = num1;
%{int_list} = num4;

Parameters
expr

Expression that resolves to an integer type or a list of integer types. You can enter one
or more expressions with the bit concatenation operator.

Description
This description is presented in three parts:

When Used on the Righthand Side of an Assignment

When Used on the Lefthand Side of an Assignment

Return Value Type

When Used on the Righthand Side of an Assignment


When used on the righthand side of an assignment, the bit concatenation operator creates a list from the
expression(s) entered by concatenating the expression values. This form is the same as
pack(packing_high,..): the most significant bit of the first physical field or lowest list item is placed at
the highest index in the resulting list of bit. In other words:

value-exp = %{exp1, exp2,...} is equivalent to value-exp = pack(packing.high, exp1, exp2, ...).

Specman e Language Reference


1999-2015

115
.

Product Version 15.1


All Rights Reserved.

For instance, as illustrated in the Example below, the following code:


...
num2 = 0x1234;
num3 = 0xabcd;
num1 = %{num2, num3};
print num1;
...

Results in:
...
num1 = 0x1234abcd

When Used on the Lefthand Side of an Assignment


When used on the lefthand side of an assignment, the bit concatenation operator unpacks the value of the
righthand side of the assignment into the expression(s) entered. This form is the same as
unpack(packing_high,..). In other words:

%{exp1, exp2,...} = value-exp is equivalent to unpack(packing.high, value-exp, exp1, exp2, ...).

For instance, as illustrated in the Example below, the following code:


...
num1 = 0x98765432;
%{num2, num3} = num1;
print num2, num3;
...

Results in:
...
num2 = 0x9876
num3 = 0x5432

The Example below also illustrates the use of the bit concatenation operator on one argument only:
...
num4 = 0x5432;
%{intlist} = num4;
print intlist;
...

Results in:
intlist =

(4 items, hex):
2 3 4 5

Specman e Language Reference


1999-2015

116

.0

Product Version 15.1


All Rights Reserved.

Return Value Type


The return value is implicitly cast to match the type of the variable or field that receives it. If there is no
receiving variable or field, the return value is a list of bit.
Note that bit concatenations are untyped expressions. See Untyped Expressions on page 166 for more
information.

Example
This example shows several uses of the bit concatenation operator.
extend sys {
setup() is also {
set_config(print, radix, HEX);
;
run() is also {
var num1 : uint (bits : 32);
var num2 : uint (bits : 16);
var num3 : uint (bits : 16);
var bilist : list of bit;
var bylist : list of byte;
var num4: int(bits: 16);
var intlist: list of int(bits: 4);
num2 = 0x1234;
num3 = 0xabcd;
num1 = %{num2, num3};
print num1;
num1 = 0x98765432;
%{num2, num3} = num1;
print num2, num3;
print %{num2, num3};
bilist = %{num2, num3};
print bilist;
bylist = %{num2, num3};
print bylist;
num4 = 0x5432;
%{intlist} = num4;
print intlist;
};
};

Specman e Language Reference


1999-2015

117
.

Product Version 15.1


All Rights Reserved.

Result
num1 = 0x1234abcd
num2 = 0x9876
num3 = 0x5432
% {num2, num3} =

(32 items, hex):

bilist =

(32 items, hex):

bylist =

(4 items, hex):

intlist =

9 8 7 6

5 4 3 2

.0

9 8 7 6

5 4 3 2

.0

98 76 54 32

.0

2 3 4 5

.0

(4 items, hex):

See Also

A Simple Example of Packing on page 1034

A Simple Example of Unpacking on page 1036

pack() on page 1059

unpack() on page 1064

swap() on page 1069

do_pack() on page 1071

do_unpack() on page 1075

1.12 Scalar Modifiers


You can create a scalar subtype by using a scalar modifier to specify the range or bit width of a scalar
type. The following sections describe the scalar modifiers:

[ range,...] on page 119

(bits | bytes : width-exp) on page 120

See Also

Scalar Types on page 138

type sized scalar on page 187

type scalar subtype on page 185

Specman e Language Reference


1999-2015

118

Product Version 15.1


All Rights Reserved.

1.12.1

[ range,...]

Purpose
Range modifier

Category
Range

Syntax
[range, ...]
Syntax Example
u: uint[5..7, 15];

Parameter
range

Either a constant expression, or a range of constant expressions in the form:


low-value..high-value

If the scalar type is an enumerated type, it is ordered by the value associated with the integer
value of each type item.

Description
Creates a scalar subtype by restricting the range of valid values.

Example 1
The following example shows how to limit the values of an enumerated type and a numeric type.
<'
type color:[red, orange, yellow, green, blue, purple];
extend sys {
bright: color[red..yellow];
u: uint[5..7, 15];
};
'>

Specman e Language Reference


1999-2015

119
.

Product Version 15.1


All Rights Reserved.

See Also

Scalar Subtypes on page 140

type scalar subtype on page 185

1.12.2

(bits | bytes : width-exp)

Purpose
Define a sized scalar

Category
Expression

Syntax
(bits|bytes: width-exp)
Syntax Example
type word
:uint(bits:16);
type address :uint(bytes:2);

Parameter
width-exp

A positive constant expression. The valid range of values for sized scalars is limited
to the range 1 to 2n - 1, where n is the number of bits or bytes.

Description
Defines a bit width for a scalar type. The actual bit width is exp * 1 for bits and exp * 8 for bytes. In the
syntax example shown above, both types word and address have a bit width of 16.

Example
type word
:uint(bits:16);
type address :uint(bytes:2);

Specman e Language Reference


1999-2015

120

Product Version 15.1


All Rights Reserved.

See Also

Scalar Types on page 138

type sized scalar on page 187

1.13 Parentheses
You can use parentheses freely to group terms in expressions, to improve the readability of the code.
Parentheses are used in this way in some examples in this manual, although they are not syntactically
required.
Parentheses are required in a few places in e code, such as at the end of the method or routine name in
all method definitions, method calls, or routine calls. Required parentheses are shown in boldface in the
syntax listings in this manual.
The following sections describe the contexts in which the parentheses are required to invoke a method,
pseudo-method, or routine:

list-method() on page 121

Calling C Routines from e in the Specman Integrators Guide

Calling Predefined Routines on page 1610

Invoking Methods on page 535

1.13.1

list-method()

Purpose
Execute list pseudo-method

Category
Expression

Syntax
list-exp. list-method([param,]...)[.list-method([param,]...). ...]
Syntax Example
print me.my_list.is_empty();

Specman e Language Reference


1999-2015

121
.

Product Version 15.1


All Rights Reserved.

Parameters
list-exp

An expression that returns a list.

list-method

One of the list pseudo-methods described in Chapter 25 List Pseudo-Methods

Description
Executes a list pseudo-method on the specified list expression, item by item. When an item is evaluated,
it stands for the item and index stands for its index in the list.
When a parameter is passed, that expression is evaluated for each item in the list.

Example 1
This example shows how to call two simple list pseudo-methods. The is_empty() list method returns a
Boolean, while size() returns an int.
<'
extend sys {
my_list: list of int;
run() is also {
print me.my_list.is_empty();
assert (me.my_list.size() > 5)
};
};
'>

Result
me.my_list.is_empty() = FALSE

Example 2
List method calls can be nested within any expression as long as the returned type matches the context.
The following example filters the list my_packets to include only the ethernet kind, sorts the result in
ascending order, and prints.
<'
struct packet {
kind: [ethernet, atm, other];
size: uint;
};

Specman e Language Reference


1999-2015

122

Product Version 15.1


All Rights Reserved.

extend sys {
packets[10]: list of packet;
run() is also {
print packets.all(.kind==ethernet).sort(.size);
};
};
'>

Result
packets.all(.kind==ethernet).sort(.size) =
item
type
kind
size
--------------------------------------------------------------0.
packet
ethernet
895996206
1.
packet
ethernet
960947360
2.
packet
ethernet
3889995846

See Also

Chapter 25 List Pseudo-Methods

Implicit Variables on page 62

1.14 Special-Purpose Operators


Specman supports the following special purpose operators:
is [not] a on page 123

Identify the subtype of a struct instance

new on page 125

Allocate a new struct

. on page 128

Refer to fields in structs

' on page 131

Used in names of e entities

? : on page 131

Conditional operator

evaluate { ... } on page 133

Evaluate actions inside an expression syntactic element

1.14.1

is [not] a

Purpose
Identify the subtype of a struct instance
Specman e Language Reference
1999-2015

123
.

Product Version 15.1


All Rights Reserved.

Category
Boolean expression

Syntax
struct-exp is a subtype [(name)]
struct-exp is not a subtype
Syntax Example
if me is a long packet (l) {
print l;
};
if me is not a long packet {
print kind;
};

Parameters
struct-exp

An expression that returns a struct.

subtype

A subtype of the specified struct type.

name

The name of the local variable you want to create. This parameter cannot be used
with is not a expressions.

Description
Identifies whether a struct instance is a particular subtype or not at run time.
If a name is specified, then a local temporary variable of that name is created in the scope of the action
containing the is a expression. This local variable contains the result of struct-exp.as_a(type) when the
is a expression returns TRUE.

Notes

A compile time error results if there is no chance that the struct instance is of the specified type.
Unlike other constructs with optional name variables, the implicit it variable is not created when the
optional name is not used in the is a expression.
The name parameter cannot be used with is not a expressions.

Specman e Language Reference


1999-2015

124

Product Version 15.1


All Rights Reserved.

Example
<'
type pack_kind: [long, short];
struct packet {
kind: pack_kind;
when long packet {
a: int;
};
check_my_type() is {
if me is a long packet (l) {
print l;
};
if me is not a long packet {
print kind;
};
};
};
extend sys {
p:packet;
};
'>

Result
cmd-prompt> sys.p.check_my_type()
l = packet-@0: packet
---------------------------------------------- @expressions67
0
kind:
long
1
long'a:
-1786485835

See Also

as_a() on page 194

1.14.2

new

Purpose
Allocate a new initialized struct

Specman e Language Reference


1999-2015

125
.

Product Version 15.1


All Rights Reserved.

Category
Expression

Syntax
[a] new [struct-type [(name)]] [with {action;...}]
Syntax Example
var q: packet = new good large packet;

Parameters
struct-type

Either a struct type or a struct subtype.

name

An optional name, valid within the action block, for the new struct. If no name is
specified, you can use the implicit variable it to refer to the new struct.

action

A list of one or more actions.

Description
Creates a new struct:
1.

Allocates space for the struct.

2.

Initializes default values:

Sets the initial value of the struct to NULL.


Sets the initial value of lists to (empty), unless the list is a sized list of scalars, in which case it
is initialized to the proper size with each item set to the default value.
Sets the initial value of all fields of scalar type, including enumerated scalar type, to zero.

3.

Invokes the init() method for the struct. Executes the action-block, if one is specified.

4.

Invokes the run() method for the struct, unless the new expression is in a construct that is executed
before the run phase. For example, if you use new in an extension to sys.init(), then the run() method
is not invoked.

If no subtype is specified, the type is derived from the context. For example, if the new struct is assigned
to a variable of type packet, the new struct will be of type packet.
If the with clause is used, you can refer to the newly created struct either with the implicit variable it, or
with an optional name. Example:
Specman e Language Reference
1999-2015

126

Product Version 15.1


All Rights Reserved.

var a: A;
a = new with {
it.f = 5;
};

Note
The new struct is a shallow struct. The fields of the struct that are of type struct are not allocated.

Example
<'
struct packet {
good : bool;
size : [small, medium, large];
length : int;
};
extend sys {
run() is also {
var p : packet = new;
print p;
var q : packet = new good large packet;
print q;
var x := new packet (p) with {
p.length = 5;
print p;
};
};
};
'>

Result
p = packet-@0: packet
---------------------------------------------- @expressions69
0
good:
FALSE
1
size:
small
2
length:
0
q = good large packet-@1: good large packet
---------------------------------------------- @expressions69
0
good:
TRUE
1
size:
large
2
length:
0
p = packet-@2: packet
Specman e Language Reference
1999-2015

127
.

Product Version 15.1


All Rights Reserved.

---------------------------------------------0
good:
FALSE
1
size:
small
2
length:
5

@expressions69

See Also

The init() Method of any_struct or any_unit on page 1186

The run() Method of any_struct or any_unit on page 1192

Struct Subtypes on page 150

1.14.3

Purpose
Refer to fields in structs

Category
Expression

Syntax
[[struct-exp].] field-name
Syntax Example
keep soft port.sender.cell.u == 0xff;

Parameters
struct-exp

An expression that returns a struct.

field-name

The name of the scalar field or list field to reference.

Description
Refers to a field in the specified struct. If the struct expression is missing, but the period exists, the
implicit variable it is assumed. If both the struct expression and the period (.) are missing, the field name
is resolved according to the name resolution rules.

Specman e Language Reference


1999-2015

128

Product Version 15.1


All Rights Reserved.

Notes

When the struct expression is a list of structs, the expression cannot appear on the left-hand side of
an assignment operator.
When the field name is a list item, the expression returns a concatenation of the lists in the field.

Example 1
The following example shows the use of the . to identify the fields u and kind in the keep constraints:
<'
struct switch {
ctrl: ctrl_stub;
port: port_stub;
keep soft port.sender.cell.u == 0xff;
keep ctrl.init_command.kind == RD;
};
struct ctrl_stub {
init_command: ctrl_cmd;
};
struct simplex {
kind: [TX, RX];
cell: cell;
};
struct port_stub {
sender: TX simplex;
listener: RX simplex;
};
struct cell {
u: uint;
};
struct ctrl_cmd {
kind: [RD, WR];
addr: int;
};
extend sys {
switch : switch;
};
'>

Example 2
This example shows the effect of using the . to access the fields in a list (switch.port) and to access a
field that is a list (switch.port.data):

Specman e Language Reference


1999-2015

129
.

Product Version 15.1


All Rights Reserved.

<'
struct switch {
port: list of port_stub;
keep soft port.size() == 4;
};
struct port_stub {
data[5]: list of byte;
};
extend sys {
switch: switch;
run() is also {
print switch.port;
print switch.port.data;
};
};
'>

Result
switch.port =
item
type
data
--------------------------------------------------------------0.
port_stub
(5 items)
1.
port_stub
(5 items)
2.
port_stub
(5 items)
3.
port_stub
(5 items)
switch.port.data = (20 items, dec):
185 24 137 186 202
3 186 107 108 119 84 212
.0
129 224 56 145
3 252 61 58
.12

See Also

Struct Hierarchy and Name Resolution on page 54

Specman e Language Reference


1999-2015

130

Product Version 15.1


All Rights Reserved.

1.14.4

'

Apostrophes
The apostrophe (') is an important syntax element used in multiple ways in e source code. The actual
context of where it is used in the syntax defines its purpose. A single apostrophe is used in the following
places:

When accessing HDL objects (for example: 'top.a')


When defining the name of a syntactic construct in a macro definition (for example:
show_time'command)
When referring to struct subtypes (for example: b'dest Ethernet packet)
When referring to an enumerated value not in context of an enumerated variable (for example:
color'green)
In the begin-code marker <' and in the end-code marker '>

See Also

Reading and Writing HDL Objects in the Specman Integrators Guide

Chapter 21 Macros

Struct Subtypes on page 150

Enumerated Type Values on page 61

Code Segments on page 34

1.14.5

?:

Purpose
Conditional operator

Category
Expression

Syntax
bool-exp ? exp1 : exp2

Specman e Language Reference


1999-2015

131
.

Product Version 15.1


All Rights Reserved.

Syntax Example
z = (flag ? 7 : 15);

Parameters
bool-exp

A legal e expression that evaluates to TRUE or FALSE.

exp1, exp2

A legal e expression.

Description
Evaluates one of two possible expressions, depending on whether a Boolean expression evaluates to
TRUE or FALSE. If the Boolean expression is TRUE, then the first expression is evaluated. If it is
FALSE, then the second expression is evaluated.

Example
<'
extend sys {
run() is {
var z: int;
var flag: bool;
z = (flag ? 7 : 15);
print flag, z;
};
};
'>

Result
flag = FALSE
z = 15

See Also

Conditional Actions on page 561

Specman e Language Reference


1999-2015

132

Product Version 15.1


All Rights Reserved.

1.14.6

evaluate { ... }

Purpose
Enable execution of actions inside an expression

Category
Expression

Syntax
evaluate [type] [(var-name)] { action; ... }
Syntax Example
evaluate (value<?>) {

Parameters
type

Type of the expression and implicit variable. Optional.


A specified type cannot contradict the context or an error will result.
If no type is specified, the type is inferred from the context of the expression, and
if it cannot be inferred, an error will result.
Cadence recommends that you explicitly specify the type, especially for macros.

var-name

Name that is valid within the action block, and that you give to specify the
variable the respresents the expression. Optional.
If you do not include this parameter, the value of the expression is referred to by
the implicit variable value.
The variable is visible only from inside the block. Its value before any
assignments is the default value for its type. Cadence recommends that you
explicitly name the implicit variable to avoid confusion about the contents of
value.

Specman e Language Reference


1999-2015

133
.

Product Version 15.1


All Rights Reserved.

action; ...

A sequence of zero or more actions separated by semicolons and enclosed in


curly braces. Once evaluation of all the actions completes, the value of the
implicit variable (var-name) becomes the value of the expression.
Note the following limitations:

Temporal expressions can't be used inside the block; however procedural


expressions that address temporal entities are OK: "emit event", "now
@event".
"return" action can't be used inside the block.
"break" and "continue" can be used only for loops defined inside the block,
not for enclosing loops.

Description
This construct is intended to overcome the language limitation that very strictly distinguished between
actions and expressions. It is especially useful for defining expression macros with actions inside.
Notes

Cadence discourages using this syntax in regular procedural code without strong justification, because
it might make the code less readable and maintainable.
In context of macros, it is not always possible to add a syntactic parameter of type when its type is
defined by some expression parameter. In this case, the operator typeof() / typeof_item() on page
191 operator can be used.

Example 1
Define list pseudo-method:
<'
define <my_n_index'exp> "<list'exp>.my_n_index\(<num'exp>, <item'exp>\)"
as {
evaluate int (res<?>) {
res<?> = UNDEF;
var match<?>: int;
var num<?>: int = <num'exp>;
for each in <list'exp> { // loop creates it and index variables
if <item'exp> {
match<?> += 1;
if match<?> == num<?> {
res<?> = index;
break;
};
};
Specman e Language Reference
1999-2015

134

Product Version 15.1


All Rights Reserved.

};
};
};
...
idx = my_list.my_n_index(get_n(), index != 0 and it != NULL and it.i > 0);
...
'>

Example 2
Use of action-related constructs in macro:
<'
define <get_value_with_gen'exp> "get_value using <var'type> <block>" as {
evaluate (value<?>) {
var var<?>: <var'type>;
gen var<?> keeping <block>;
value<?> = var<?>.get_value();
};
};
...
var new_value := get_value using gen_type_s { .kind == GOOD; .size == BIG };
...
define <get_and_start'exp>
"get <get'name>\(<get_p'exp>,...\) and_start
<tcm'name>\(<tcm_p'exp>,...\)"
as {
evaluate typeof(<get'name>(<get_p'exps)) (val<?>) {
val<?> = <get'name>(<get_p'exps>);
start <tcm'name>(<tcm_p'exps>);
};
};
...
var sending_time := get curr_time() and_start send(packet);
...
'>

Example 3
Complex control flow actions in exp:
<'
define <find_target'exp> "find_correct_target" as {
evaluate typeof(get_target_for_bad_red()) (t<?>) {

Specman e Language Reference


1999-2015

135
.

Product Version 15.1


All Rights Reserved.

case {
me is a BAD RED packet: {
t<?> = get_target_for_bad_red();
};
me.kind is BAD and me.data.size() > 64: {
if not me.data.has(it != 0) {
t<?> = get_target_for_blank();
else {
t<?> = get_target_for_bad();
};
me.data.size() <= 64: {
t<?> = get_target_for_small();
};
default: {
t<?> = get_generic_target();
};
};
};
};
...
find_correct_target.foo();
...
'>

Specman e Language Reference


1999-2015

136

Product Version 15.1


All Rights Reserved.

Data Types

The e language has a number of predefined data types including the integer and Boolean scalar types
common to most programming languages. In addition, you can create new scalar data types (enumerated
types) that are appropriate for programming, modeling hardware, and interfacing with hardware
simulators. The e language also provides a powerful mechanism for defining object-oriented
hierarchical data structures (structs) and ordered collections of elements of the same type (lists).
This chapter contains the following topics:

e Data Types on page 137

Memory Requirements for Data Types on page 165

Untyped Expressions on page 166

Assignment Rules on page 169

Precision Rules for Numeric Operations on page 176

Automatic Type Casting on page 180

Defining and Extending Scalar Types

Referring to Types in Generic Code

Converting from One Data Type to Another on page 194

Accessing All Values of a Scalar Type on page 209

See Also

Chapter 3 Structs, Fields, and Subtypes

Chapter 1 e Basics

2.1

e Data Types

Most e expressions have an explicit data type. These data types are described in the following sections:
Specman e Language Reference
1999-2015

137
.

Product Version 15.1


All Rights Reserved.

Scalar Types on page 138

Scalar Subtypes on page 140

The set Type on page 142

Enumerated Scalar Types on page 145

Struct Types on page 149

Struct Subtypes on page 150

List Types on page 155

The string Type on page 158

The real Type on page 158

The external_pointer Type on page 164

The untyped Pseudo Type on page 164

See Also

Certain expressions, such as HDL objects, have no explicit data type. See Untyped Expressions on
page 166 for information on how Specman handles these expressions.
Chapter 26 Set Pseudo-Methods

2.1.1

Scalar Types

Scalar types in e are one of the following:

Numeric
Boolean
Enumerated

Specman e Language Reference


1999-2015

138

Product Version 15.1


All Rights Reserved.

2.1.1.1

Predefined Scalar Types

Table 2-1 on page 139 shows Specman predefined scalar types.

Table 2-1

Specman Predefined Scalar Types

Type
Name

Function

Default Size for


Packing

Default
Value

int

Signed integer in range from -231 to 231-1.

32 bits (for both 32-bit


and 64-bit Specman)

uint

Unsigned integer in range from 0 to 232-1.

32 bits

longint

Signed integer in range from -263 to 263-1.

64-bit

longuint

Unsigned integer in range from 0 to 264-1.

64-bit

bit

Unsigned integer in the range 01.

1 bit

nibble

Unsigned integer in the range 0-15.

byte

Unsigned integer in the range 0255.

8 bits

time

Integer in the range 0264-1.

64 bits

bool

Represents truth (logical) values, TRUE(1)


and FALSE (0).

1 bit

FALSE (0)

Unsigned integers can be of any size and, thus, of any range. See Scalar Subtypes on page 140 for
information on how to specify the size and range of a scalar field or variable explicitly.

See Also

Scalar Subtypes on page 140

Enumerated Scalar Types on page 145

Assignment Rules on page 169

Defining and Extending Scalar Types on page 182

Accessing All Values of a Scalar Type on page 209

Literals and Constants on page 35

bool-constraint-def on page 619

Packages as Namespaces for Types in the Creating e Testbenches

Specman e Language Reference


1999-2015

139
.

Product Version 15.1


All Rights Reserved.

2.1.2

Scalar Subtypes

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.
Infinite (unbounded) integers are a predefined scalar subtype.
Types longint and longuint cannot be used to create subtypes.

In This Section

Scalar Modifiers on page 140

Named Scalar Subtypes on page 141

Infinite (Unbounded or Long) Integers on page 141

See Also

type enumerated scalar on page 183

type scalar subtype on page 185

type sized scalar on page 187

2.1.2.1

Scalar Modifiers

There are two types of scalar modifiers that you can use together or separately to modify predefined
scalar types:
1.

Range modifiers

2.

Width modifiers

Range modifiers define the range of valid generatable values. For example, the range modifier in the
expression below restricts valid values to those between zero and 100 inclusive.
struct dtypes {
m() is {
var d1:int [0..100];
};
};

Width modifiers define the width in bits or bytes. The width modifiers in the expressions below restrict
the bit width to 8.
var d2: int (bits: 8);
var d3: int (bytes: 1);
Specman e Language Reference
1999-2015

140

Product Version 15.1


All Rights Reserved.

You can use width and range modifiers in combination.


var d4: int [0..100] (bits: 7);

See Also

Assignment of Numeric Types on page 171

2.1.2.2

Named Scalar Subtypes

When you use a scalar modifier to limit the range or bit width of a scalar type, you can also specify a
name.
Named scalar subtypes are useful in a context where, for example, you need to declare a counter variable
like the variable count several places in the program.
var count : int [0..100] (bits:7);

By creating a named scalar type, you can use the type name when introducing new variables with this
type.
type int_count : int [0..99] (bits:7);
var count : int_count;

See Also

Assignment of Enumerated Types on page 172

2.1.2.3

Infinite (Unbounded or Long) Integers

Infinite integers represent arbitrarily large positive or negative numbers. Infinite integers are specified
as:
int (bits: *)

You can use an infinite integer variable when you do not know the exact size of the data. You can use
infinite integers in expressions just as you use signed or unsigned integers.
Notes

Fields or variables declared as infinite integers cannot be generated, packed, or unpacked.


Infinite unsigned integers are not allowed, so a declaration of a type such as uint (bits:*) generates
a compile-time error.

Specman e Language Reference


1999-2015

141
.

Product Version 15.1


All Rights Reserved.

See Also

Understanding Semantics Used in Constraints Versus Semantics Used in Procedural Code in

Specman Generation User Guide

2.1.3

The set Type

Expressions of the e type set evaluate to a defined set of integer values. Following is an example
illustrating usage of the set data type:
struct s {
foo() is {
var s1: set;
var s2: set = [3..7, 10..13]
print 5 in s2; // prints TRUE
print 8 in s2; // prints FALSE
s1 = s2;
// s1 is [3..7, 10..13]
s2 = [4..5];
// s1 is not changed
print s1 in s2; // prints FALSE
print s2 in s2; // prints TRUE
var x: int;
gen x keeping {it in value(s2)}; // x may become 4 or 5
};
};

Notes

If the type of the elements included in a set type cannot be determined by the context in which it is
used, it is considered an integer set.
The [] set is an empty set. This is the default value of the set type.

This Topic
The following describe sets and the set type in more detail:

Set Literals on page 143

Restrictions on Sets on page 144

Set Operations on page 144

String Representation of set Type on page 145

Responding to the Warning WARN_INT_UINT_SET_SEMANTICS on page 145

Specman e Language Reference


1999-2015

142

Product Version 15.1


All Rights Reserved.

See Also

Using Sets in Constraints in the Specman Generation User Guide

2.1.3.1

Set Literals

Set literals are used to define expressions of type set in the form [interval, ...]. The interval can be an
integer expression or an integer range in the form:
low-value..high-value

Following are some examples of set literals. These examples assume that x, y, and z evaluate to integers:
[1..5, 10]
[x..y, z+5]
[x..10]
[min(x,y)..max(x,y)]

Notes

Both constant values and variables are supported in set literals.

The values can evaluate to signed or unsigned numbers or to integers of any bit size.
Note For best performance, do not mix numeric types in a given set. For example, include all
signed integers or all unsigned integers in a given set.

The ranges defined by set literals can overlap, for example, [2..7, 4..9]. The members of this set
evaluate to [2..9].

When Variables Are Not Allowed in Set Literals


When set literals are used in contexts other than expressions or constraints, they must evaluate to
constant values. Examples of such usage include:

A subrange modifier for scalar types, for example, type t: int[1..10,15..20].

An item in a case clause, for example:


case x {
[1..10,15..20]: {}
}

A cover item range option.

Variables or other non-constant expressions are not allowed in set literals in these contexts.

Enumerated Types as Set Literals


Rules for using enumerated types as set literals:
Specman e Language Reference
1999-2015

143
.

Product Version 15.1


All Rights Reserved.

Only constant enumerated values are supported and all values in a given set literal must be of the
same enumerated type.
Enumerated types can be used only in set literals in:

The right-hand side of the in operator. (The left-hand side must be an expression of the same
enumerated type.)
The items described above in When Variables Are Not Allowed in Set Literals on page
143subrange modifiers for scalar types, case clauses, and cover item ranges.

The values are ordered by the value associated with the integer value of each type item.

Example:
var c:[red, green, blue, yellow];
c in [red..blue];

Note

The following code causes a compilation error because of type incompatibility:

var c: [red, green, blue, yellow]


c in [1..3] // Illegal

For more information, see Enumerated Scalar Types on page 145.

2.1.3.2

Restrictions on Sets

Items of type set cannot be generated. They can be used as inputs to generation only. (For more
information, see Using Sets in Constraints in the Specman Generation User Guide.)
Note

You cannot use items of type set, even as inputs, with the Pgen generator.

Variables of the set type cannot be passed as parameter by reference.

Items of the set type cannot be packed or unpacked.

Items of the set type cannot be used as a key in keyed list.

The C interface is not supported for the set type.

2.1.3.3

Set Operations

You can use the following operators on e sets:

Equality. See == != on page 89.

Assignment. See Assignment of Sets on page 175.

Membership or inclusion. See in on page 96.

You can also use the set pseudo-methods on e sets. See Chapter 26 Set Pseudo-Methods.
You can also use the type for each in set on page 575.
Specman e Language Reference
1999-2015

144

Product Version 15.1


All Rights Reserved.

2.1.3.4

String Representation of set Type

The string representation of values of type set shows it as a set literal:

The minimum number of intervals is shown, meaning that there are no overlapping or neighboring
intervals. Examples:
[1..5, 3..15].to_string()
[1..5, 6..15].to_string()

=>
=>

Single value intervals are shown with the single value. Example:
[1..5, 10..10].to_string()

"[1..15]"
"[1..15]"

=>

"[1..5, 10]"

The intervals are shown in ascending order. Example:


[10..15, 1..5].to_string()

2.1.3.5

=>

"[1..5, 10..15]"

Responding to the Warning


WARN_INT_UINT_SET_SEMANTICS

The warning WARN_INT_UINT_SET_SEMANTICS indicates that instances in your e code of


expressions formatted as exp in list-of-ranges may not be interpreted as you expect.
Previous to version 12.2, the numeric type of exp was used as the type context for values in
list-of-ranges. As of 12.2, list-of-ranges is evaluated independently, with int(bits:*) semantics.
Following is an example illustrating this situation:
var x: uint;

if x in [-5..-1] {}

Previous to 12.2, because x is of type uint, the range evaluated to [-5.as_a(uint)..-1.as_a(uint)], which is
equal to [4294967291..MAX_UINT].
In 12.2 and after, [-5..-1] is evaluated to [-5..-1]. In this case, given that x is of type uint (in other words,
whose domain is [0..MAX_UINT]), x is always out of range.

2.1.4

Enumerated Scalar Types

You can define the valid values for a variable or field as a list of symbolic constants. For example, the
following declaration defines the variable kind as having two legal values.
var kind: [immediate, register];

Specman e Language Reference


1999-2015

145
.

Product Version 15.1


All Rights Reserved.

In this Section

Integers Associated with the Enumerated Constants on page 146

Assigning Values to the Enumerated Constants on page 147

Naming an Enumerated Type on page 147

Extending and Sizing Enumerated Types on page 147

Casting of Enumerated Types in Comparisons on page 148

See Also

Assignment of Enumerated Types on page 172

type enumerated scalar on page 183

extend type on page 189

2.1.4.1

Integers Associated with the Enumerated Constants

The symbolic constants defined for an enumerated type 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.
var kind: [immediate = 1, register = 2];

The associated unsigned integer value of a symbolic constant in an enumerated type can be obtained
using the .as_a() type casting operator. Similarly, an unsigned integer value that is within the range of
the values of the symbolic constants can be cast as the corresponding symbolic constant.
Casting an unsigned integer to a symbolic constant:
type signal_number: [signal_0, signal_1, signal_2, signal_3];
struct signal {
cast_1() is {
var temp_val: uint = 2;
var signal_name: signal_number = temp_val.as_a(signal_number);
print signal_name;
};
};

Casting a symbolic constant to an unsigned integer:


type signal_number: [signal_0, signal_1, signal_2, signal_3];
struct signal {
cast_2() is {
var temp_enum: signal_number = signal_3;
var signal_value: uint = temp_enum.as_a(uint);
Specman e Language Reference
1999-2015

146

Product Version 15.1


All Rights Reserved.

print signal_value;
};
};

See Also

Assignment of Enumerated Types on page 172

Casting of Enumerated Types in Comparisons on page 148

Converting from One Data Type to Another on page 194

2.1.4.2

Assigning Values to the Enumerated Constants

You can explicitly assign values to some symbolic constants and allow others to be automatically
assigned. The following declaration assigns the value 3 to immediate; Specman assigns the value 4 to
register automatically.
var kind: [immediate = 3, register];

2.1.4.3

Naming an Enumerated Type

You can name an enumerated type to facilitate its reuse throughout your program. For example, the first
statement below defines a new enumerated type named instr_kind. The variable i_kind has the two
legal values defined by the instr_kind type.
type instr_kind: [immediate, register];
var i_kind: instr_kind;

It is sometimes convenient to introduce a named enumerated type as an empty type.


type packet_protocol: [];

See Also

type enumerated scalar on page 183

2.1.4.4

Extending and Sizing Enumerated Types

Once the protocols that are meaningful in the program are identified you can extend the definition of the
type with a statement like:
extend packet_protocol : [Ethernet, IEEE, foreign];
Specman e Language Reference
1999-2015

147
.

Product Version 15.1


All Rights Reserved.

Enumerated types can be sized.


type instr_kind: [immediate, register] (bits: 2);

Variables or fields with an enumerated type can also be restricted to a range. This variable declaration
excludes foreign from its legal values:
var p :packet_protocol [Ethernet..IEEE];

The default value for an enumerated type is zero, even if zero is not a legal value for that type. For
example, the variable i_kind has the value zero until it is explicitly initialized or generated.
type instr_kind: [immediate = 1, register = 2];
var i_kind: instr_kind;

See Also

type enumerated scalar on page 183

extend type on page 189

Assignment of Enumerated Types on page 172

2.1.4.5

Casting of Enumerated Types in Comparisons

Enumerated scalar types, like Boolean types, are not automatically converted to or from integers or
unsigned integers in comparison operations (that is, comparisons using <, <=, >, >=, ==, or !=
operators). This is consistent with the strong typing in e, and helps avoid introduction of bugs if the
order of symbolic names in an enumerated type declaration is changed, for example, while operations
which are affected by the order of those names in the declaration remain unchanged (because they are in
a different part of the code and therefore go unnoticed, perhaps).
Assume that I is an int, B is a bool, and E is an enumerated type. Since enumerated and boolean types
are not automatically converted to or from integers or unsigned integers, you cannot use syntax such as
if (I) {...}, or if (B==1) {...}, or if (E<6) {...}. In order to perform such comparisons, you must use
explicit casting, or tick notation to specify the type. Examples of correct and incorrect syntax are shown
in the sample code below.
type my_enum: [A, B, C];
struct etypes {
x: my_enum;
my_method() is {
if (A.as_a(int) < B.as_a(int)) then {
out("A is less than B");
};

Specman e Language Reference


1999-2015

148

// Load-time error:
// No such variable 'A'

Product Version 15.1


All Rights Reserved.

if (A.as_a(int) == B.as_a(int)) then {


out("A equals B");
};

// Load-time error:
// No such variable 'B'

if (my_enum'A.as_a(int) < my_enum'B.as_a(int)) then {


out ("A less than B");
};

// No error

if (my_enum'A < my_enum'B) then {


// Load-time error:
out ("A less than B");
// The type of 'x' is 'my_enum'
};
// while expecting a numeric type
if (x < A) then {
out("x less than A");
};

// Load-time error:
// The type of 'x' is 'my_enum'
// while expecting a numeric type

if (x == A) then {
out ("x equals A");
};

// No error

};
};

The first two if statements above cause load errors because it is possible for A or B or both to be used in
more than one enumerated type declaration, and it is not possible to tell from the context which type they
are, or their values. In the third if statement, the enumerated type is specified using the tick notation, so
that statement is legal. Note that it is still necessary to cast A and B as ints in order to do the comparison,
A < B, otherwise the error in the fourth case, my_enumA < my_enumB, occurs.
In the fifth case, x < A, the context of A is not clear at load time, so a loading error occurs. The context
of A is clear in the last case, x == A, however, so this code loads with no problem.

See Also

as_a() on page 194

2.1.5

Struct Types

Structs are the basis for constructing compound data structures.


The following statement creates a struct type called packet with a field protocol of type
packet_protocol.
struct packet {
protocol: packet_protocol;
};

Specman e Language Reference


1999-2015

149
.

Product Version 15.1


All Rights Reserved.

You can then use the struct type packet in any context where a type is required. For example in this
statement, packet defines the type of a field in another struct.
struct port {
data_in : packet;
};

You can also define a variable using a struct type.


var data_in : packet;

The default value for a struct is NULL.

See Also

Chapter 3 Structs, Fields, and Subtypes

var on page 550

2.1.6

Struct Subtypes

When a struct field has a Boolean type or an enumerated type, you can define a struct subtype for one or
more of the possible values for that field. For example, the struct packet defined below has three
possible subtypes based on its protocol field. The gen_eth_packet method below generates an
instance of the legal Ethernet packet subtype, where legal == TRUE and protocol == Ethernet.
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
legal: bool;
};
extend sys {
gen_eth_packet () is {
var packet: legal Ethernet packet;
gen packet keeping {it.size < 10;};
print packet;
};
};

This section contains the following:

Referring to a Struct Subtype on page 151

Using extend, when, and like with Struct Subtypes on page 152

Referring To Conditional Fields in when Constructs on page 153

Specman e Language Reference


1999-2015

150

Product Version 15.1


All Rights Reserved.

See Also

Extending Subtypes on page 222

var on page 550

Struct Hierarchy and Name Resolution on page 54

when on page 241

extend type on page 219

is [not] a on page 123

2.1.6.1

Referring to a Struct Subtype

To refer to a Boolean struct subtype, for example legal packet, use this syntax:
field_name struct_type

To refer to an enumerated struct subtype in a struct where no values are shared between the enumerated
types, you can use this syntax:
value_name struct_type

In structs where more than one enumerated field can have the same value, you must use tick notation
syntax as in the following to refer to the struct subtype:
value'field_name struct_type

For example, if we define two enumerated types:


type destination: [a, b, c, d];
type source: [a, b, c, d];

And add two fields to the packet struct:


dest: destination;
src: source;

The syntax for referring to the type of an Ethernet packet with the destination b is:
b'dest Ethernet packet

because the name b Ethernet packet is ambiguous.


type packet_protocol: [Ethernet, IEEE, foreign];
type destination: [a, b, c, d];
type source: [a, b, c, d];
struct packet {
protocol: packet_protocol;

Specman e Language Reference


1999-2015

151
.

Product Version 15.1


All Rights Reserved.

size: int [0..1k];


data[size]: list of byte;
legal: bool;
dest: destination;
src: source;
};
extend sys {
gen_eth_packet () is {
var packet: b'dest Ethernet packet;
gen packet keeping {it.size > 511 and it.size < 1k};
print packet;
};
};

The example below shows another context where a struct subtype can be used.
type packet_protocol: [Ethernet, IEEE, foreign];
type destination: [a, b, c, d];
type source: [a, b, c, d];
struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
legal: bool;
dest: destination;
src: source;
};
extend sys {
plist: list of packet;
print_Epackets() is {
for each Ethernet packet (ep) in plist {
print ep;
};
};
};

2.1.6.2

Using extend, when, and like with Struct Subtypes

You can also use the extend, when, or like constructs to add fields, methods, or method extensions that
are required for a particular subtype.
For example, the extend construct shown below adds a field and a method to the Ethernet packet
subtype. The Ethernet packet subtype also inherits all the characteristics of the struct packet.
type packet_protocol: [Ethernet, IEEE, foreign];

Specman e Language Reference


1999-2015

152

Product Version 15.1


All Rights Reserved.

struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
};
extend Ethernet packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};

The Ethernet packet subtype could also be defined with the when construct. The following Ethernet
packet subtype is exactly equivalent to the Ethernet packet subtype defined by extend.
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
when Ethernet packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};
};

You can use either the when or the extend construct to define struct subtypes with very similar results.
These constructs are appropriate for most modeling purposes. Under certain circumstances, you may
prefer to use the like construct to create struct subtypes.

See Also

Extending Subtypes on page 222

Extending When Subtypes on page 244

Comparison of When and Like Inheritance on page 252

2.1.6.3

Referring To Conditional Fields in when Constructs

The example below shows how to refer to a field of a struct subtype outside of a when, like, or extend
construct by assigning a temporary name to the struct subtype.
type packet_protocol: [Ethernet, IEEE, foreign];
Specman e Language Reference
1999-2015

153
.

Product Version 15.1


All Rights Reserved.

struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
keep me is a Ethernet packet (ep) => ep.e_field == 1;
when Ethernet packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};
};

In order to reference a field in a when construct, you must specify the appropriate value for the when
determinant. For example, consider the following struct and subtype:
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
when IEEE packet {
i_val: int;
};
};

For any instance pk_inst of the packet struct, references to the i_val field are only valid if the when
determinant is IEEE. The following are three ways to ensure that pk_inst is in fact an IEEE packet
before referencing i_val.

Test pk_inst to see if it is IEEE packet:


if pk_inst is a IEEE packet (ip) {ip.i_val = 1; };

or
pk_list.first(it is a IEEE packet (ip) and ip.i_val == 1);

Use this method if pk_inst is a packet that may or may not be IEEE. For example, pk_inst
may be an element of a list of packets or may be a generated packet with no constraint on
protocol.

Define pk_inst as an IEEE packet:


var pk_inst: IEEE packet;
pk_inst.i_val = 1;

or
var pk_inst: IEEE packet;
gen pk_inst keeping {

Specman e Language Reference


1999-2015

154

Product Version 15.1


All Rights Reserved.

it is a IEEE packet (ip) and ip.i_val == 1


};

Use this method if you want pk_inst to always be IEEE. Note that you must either declare the
variable or field to be type IEEE packet or use the is a syntax. It is not sufficient to say gen
pk_inst keeping (.kind == IEEE; .i_val == 1}.

Cast pk_inst as IEEE packet:


pk_inst.as_a(IEEE packet).i_val = 1;

This is shorthand for method 1 above. You can do it this way if you know that pk_inst is an IEEE
packet but for some reason it is defined just as a packet. For example:
var pk_inst: packet;
gen pk_inst keeping {it is a IEEE packet};
pk_inst.as_a(IEEE packet).i_val = 1;

Note that if pk_inst is not an IEEE packet you will get an error stating that struct is NULL.

2.1.7

List Types

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. For example, my_list[0] refers to the first item in the list named my_list.
Lists are defined by using the list of keyword in a variable or a field definition. The example below
defines a list of bytes named lob and explicitly assigns five literal values to it. The print statement
displays the first three elements of lob, 15, 31, and 63.
var lob: list of byte = {15;31;63;127;255};
print lob[0..2];

Lists can also be multi-dimensional, that is, lists of lists. The following example defines two
multi-dimensional lists; the second one contains the first:
var matrix: list of list of int = {{1;2;3};{4;5;6}}
var matix_3d: list of list of list of int = {matrix;{{6;7;8};{9;10;11}}

The default value of a list is an empty list.


This section contains:

One-Dimensional (Regular) Lists on page 156

Multi-Dimensional Lists (Lists of Lists) on page 156

Keyed Lists on page 157

Specman e Language Reference


1999-2015

155
.

Product Version 15.1


All Rights Reserved.

See Also

Assignment of Lists on page 175

Defining List Fields on page 231

var on page 550

Packing and Unpacking Lists on page 1041

Chapter 25 List Pseudo-Methods

List Equality and Inequality in Specman Generation User Guide

Constraining Lists in Specman Generation User Guide

Using Bidirectional Generative List Pseudo-Methods in Specman Generation User Guide

2.1.7.1

One-Dimensional (Regular) Lists

The following example shows two lists, packets and all_lengths.


type packet_protocol : [Ethernet, IEEE, foreign];
type length: int [0..10];
struct packet {
protocol: packet_protocol;
len: length;
};
extend sys {
packets[10] : list of packet;
do_print() is {
var all_lengths: list of length;
all_lengths = packets.len;
print packets;
print all_lengths;
};
};

Each element of packets is a struct of type packet. Each element of all_lengths is a scalar value of
type length.
Both packets and all_lengths have 10 elements because of the explicit size [10] specified in the
packets declaration. You can only specify a list size in this manner for fields. To size lists that are
variables, you have to use a keep constraint.

2.1.7.2

Multi-Dimensional Lists (Lists of Lists)

Multidimensional lists are lists of lists. In general, Specman treats multidimensional lists the same as
regular lists; e list methods, queries, operators, and so on are valid for both regular and
multidimensional lists.
Specman e Language Reference
1999-2015

156

Product Version 15.1


All Rights Reserved.

For example, the following code illustrates the use of push() and add() to manipulate multi-dimensional
lists:
extend sys {
run() is also {
var matrix: list of list of int = {{1;2;3} ; {4;5;6}};
matrix.push({7;8;9});
assert matrix == {{1;2;3} ; {4;5;6} ; {7;8;9}};
var other_list: list of int;
gen other_list;
matrix.add(other_list);
assert matrix.top() == other_list;
};
};

There are some restrictions on the use of multi-dimensional lists. For more information, see list of on
page 231.

2.1.7.3

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 packets is a list of packets, and that the protocol
field in the packet type is used as the hash key.
Note

The key of a keyed list cannot be a multi-dimensional list and it cannot be of type real.

type packet_protocol : [Ethernet, IEEE, foreign];


struct packet {
protocol: packet_protocol;
};
var packets : list (key: protocol) of packet;

If the element type of the list is a scalar type or a string type, then the hash key must be the predefined
implicit variable it.
struct person {
name: string;
id: int;
};
struct city {
!persons: list(key: name) of person;
!street_names: list(key: it) of string;
};

Specman e Language Reference


1999-2015

157
.

Product Version 15.1


All Rights Reserved.

See Also

For a complete description, including the restrictions on keyed lists, see list(key) of on page 235

2.1.8

The string Type

The Specman 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, for example:
var message: string;
message = "Beginning initialization sequence...";

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. The print statement shown below displays /test1.
var dir: string = "/tmp/test1";
var tmp := dir.as_a(list of byte);
tmp = tmp[4..9];
print tmp.as_a(string);

The default value of a variable of type string is NULL, which is equivalent to an empty string (that is,
).
To continue a string over multiple lines, put the line continuation character \ at the end of each line
except the last.

See Also

Chapter 27 Predefined Routines

Packing and Unpacking Strings on page 1039

2.1.9

The real Type

Specman supports the real data type. Objects of type real are double precision floating point numbers,
similar to the precision of a C type double.

In this Section

Limitations for Type real on page 159

Real Literals on page 160

Predefined Real Constants for Analog Mixed-Signal (AMS) on page 161

Conversion Between Real and Numeric Types on page 162

Specman e Language Reference


1999-2015

158

Product Version 15.1


All Rights Reserved.

Conversions Between Real and Non-Numeric Types on page 162

Packing Values for real Types on page 163

Printing Real Values on page 163

See Also

Routines Supporting the real Type on page 1482

Real Number Generation with the Specman Generator in the Specman Generation User Guide

Real Number Generation with Pgen in the Specman Pgen User Guide

C Interface Macros that Support real Type Objects in Specman Integrators Guide

Integrating the e Testbench with Incisive AMS in Specman Integrators Guide

2.1.9.1

Limitations for Type real

General Limitations

A real object is acceptable in any context that requires a numeric object, except in the context of the
following operators:

Either operand of the shift operators (<<, >>)

Bitwise operators (|, &, ^)

Bitwise routines

Modulo (%)

odd()

even()

MVL operations (for numeric simple ports)

The key of a keyed list cannot be of type real.

You cannot use expressions of type real in temporal expressions.

Limitations Related to Generation of Type real

Pgen does not support generation of type real.


When Pgen is used, you must mark fields of type real as non-generatable. You can use the routines
that support real numbers in procedural code to generate the field.

Automatic casting is not performed in the generation context.

Specman e Language Reference


1999-2015

159
.

Product Version 15.1


All Rights Reserved.

Limitations Related to Coverage Items of Type real

Ranges must be specified.

Per instance coverage is not supported. However, per unit instance is supported.

Interactive cross coverage is not supported.

Limitations Related to Type real and Other Tools

The waveform-related command wave exp cannot be used with e objects of type real.

Co-Verification Link (CVL) and Incisive Software Extensions (ISX) do not support type real.

For SystemC:

The sc2e utility does not support type real.


For method ports with a SystemC agent, parameters of type real are converted automatically to
C++ double. All other types using real, such as list of real, require an explicit convertor.

2.1.9.2

Real Literals

Real literals are numbers that have a decimal point or an exponential part or both. If a decimal point
exists, there must be digits on both sides of the decimal point. Underscores can be added for readability
and are ignored.
Examples of real literals are:
Real Constant

Value

5.3876e4

53,876

4e-11

0.00000000004

1e+5

100,000

7.321E-3

0.007321

3.2E+4

32,000

0.5e-6

0.0000005

0.45

0.45

6.e10

60,000,000,000

See Also

The real Type on page 158

Specman e Language Reference


1999-2015

160

Product Version 15.1


All Rights Reserved.

2.1.9.3

Predefined Real Constants for Analog Mixed-Signal (AMS)

The following mathematical and physical real constants are defined in Specman and in user C code that
includes the SPMN-install-dir/specman/src/specman.h file.
Note All mathematical constants are prefixed by SN_M_. All physical constants are prefixed by
SN_P_.
Table 2-2

Mathematical Constants

Constant

Value

SN_M_E

SN_M_LOG2E

Logarithm base 2 of e

SN_M_LOG10E

Logarithm base 10 of e

SN_M_LN2

Natural logarithm of 2

SN_M_LN10

Natural logarithm of 10

SN_M_PI

PI

SN_M_TWO_PI

2*PI

SN_M_PI_2

PI/2

SN_M_PI_4

PI/4

SN_M_1_PI

1/PI

SN_M_2_PI

2/PI

SN_M_2_SQRTPI

2/sqrt(PI)

SN_M_SQRT2

sqrt(2)

SN_M_SQRT1_2

sqrt(1/2)

Table 2-3

Physical Constants

Constant

Value

SN_P_Q

Charge of electron in coulombs

SN_P_C

Speed of light in vacuum in


meters/sec

Specman e Language Reference


1999-2015

161
.

Product Version 15.1


All Rights Reserved.

Table 2-3

Physical Constants

Constant

Value

SN_P_K

Boltzmanns constant in
joules/kelvin

SN_P_H

Plancks constant in joules*sec

SN_P_EPS0

Permittivity of vacuum in
farads/meter

SN_P_U0

Permeability of vacuum in
henrys/meter

SN_P_CELSIUS0

Zero Celsius in kelvin

See Also

The real Type on page 158

2.1.9.4

Conversion Between Real and Numeric Types

Automatic casting is performed between the real type and other numeric types.
Converting a real type expression to a numeric type object uses the following process:
1.

The value of a real type expression is first converted to type int (bits:*) with the value of the largest
integer whose absolute value is less than or equal to the absolute value of the real number.
Note If the expressions floating-point value is infinity (inf), negative infinity (-inf), or
Not-a-Number (NaN), an error is emitted.

2.

The value is then converted to the expected numeric type.

When converting a numeric value to the real type, the number is converted to the value that is closest to
the numeric value and can be represented in the double precision format.

See Also

The real Type on page 158

2.1.9.5

Conversions Between Real and Non-Numeric Types

Automatic casting is not performed between the real type and non-numeric scalar types. You must
explicitly cast the object using the as_a() operator. For example:
Specman e Language Reference
1999-2015

162

Product Version 15.1


All Rights Reserved.

my_real = my_bool
// results in an error
my_real = my_bool.as_a(real) // no error

If you explicitly cast a non-numeric scalar type object using the as_a() operator, it is converted to a real
type object as follows:
1.
2.

The object is first converted to an integer value.


The object is then converted to a real value according to process and rules described in Conversion
Between Real and Numeric Types on page 162.

Notes

When converting a string value to real using the as_a() operator, the string is parsed as if it was a
real literal, and the value of the real literal is returned.
If the string does not conform to the definition of a real literal, an error is emitted.

See Also

The real Type on page 158

as_a() on page 194

2.1.9.6

Packing Values for real Types

Real values take up 64 bits when packed. These bits are actual bit representation of the double value.
The effect of the various packing options on real type objects is similar to their effect on an integer
(bits:64) value.

See Also

The real Type on page 158

2.1.9.7

Printing Real Values

By default, real values are printed in a similar way to the %g format of printf in C. For formatted
printing, you can use the %e, %f, and %g formats as with C.
Note Printing an integer value with the %e, %f, and %g formats causes an automatic conversion to
the real type. Printing real values with integer formatting causes an automatic conversion to int (bits:*).

See Also

The real Type on page 158

Specman e Language Reference


1999-2015

163
.

Product Version 15.1


All Rights Reserved.

2.1.10

The external_pointer Type

The external_pointer type is used to hold a pointer into an external (non-Specman) entity, such as a C
struct. Unlike pointers to structs in e, external pointers are not changed during garbage collection.
Note Like other pointers, the external_pointer type occupies 32 bits in 32-bit Specman and 64 bits
in 64-bit Specman.

See Also

routine ... is C routine in Specman Integrators Guide

General Guidelines for Using the C Interface in Specman Integrators Guide

2.1.11

The untyped Pseudo Type

The e language supplies a built-in type placeholder for untyped values, to be used when runtime values
of all types need to be manipulated in a generic way. For example, when objects are manipulated with
the Reflection API, static type checking cannot play a role and thus untyped values must be used. You
can assign values of any type to variables of the untyped pseudo type by using the unsafe() operator.
Similarly, you can use untyped values in a typed context by using unsafe().
Warning Do not declare fields of structs as 'untyped' pseudo type, because untyped values can be
corrupted during garbage collection. The only safe way to manipulate values generically is to use
untyped local variables, making sure programmatically that only legitimate castings are effected.
Keeping values generically outside the scope of a method can be done using value wrapper objects
(rf_value_holder).

See Also

unsafe() on page 164

rf_value_holder in Types in Reflection API in Creating e Testbenches

2.1.12

unsafe()

Purpose
Force casting; bypass type checking

Category
Expression
Specman e Language Reference
1999-2015

164

Product Version 15.1


All Rights Reserved.

Syntax
exp.unsafe(): type

Parameters
exp

Any legal e expression.

Description
Casts the expression to the type that is required by the context regardless of static or dynamic type rules.
This operator should be used with care and avoided wherever possible, as it can lead to type
inconsistencies. It should be used only in contexts in which the required type is explicit, such as
assignment and parameter passing to methods.

Example
This example makes use of Reflection API to read and assign a field programmatically. Here the
unsafe() operator is necessary to manipulate untyped values.
reset_id(type: rf_struct, instance: any_struct, default: int) is {
var id_field: rf_field = type.get_field("id");
assert id_field.get_type().get_name() == "int";
// cast the value to int type:
var curr_id: int = id_field.get_value_unsafe(instance).unsafe();
if curr_id == 0 {
// cast the integer value back to 'untyped':
id_field.set_value_unsafe(instance,default.unsafe());
};
};

See Also

The untyped Pseudo Type on page 164

Reflection Interface for e in Creating e Testbenches

2.2

Memory Requirements for Data Types

The amount of memory needed to store Specman data types is listed in Table 2-4.

Specman e Language Reference


1999-2015

165
.

Product Version 15.1


All Rights Reserved.

Table 2-4

Storage Sizes of Specman Data Types

Type

Size in Memory

All scalars up to 32 bits

4 bytes

Scalars larger than 32


bits

Size of a struct containing a list of bit of the appropriate size

longint and longuint

Size of a struct +8 bytes

String

The pointer (4 bytes for 32-bit Specman or 8 bytes for 64-bit Specman) +
the size of the string + 1 byte (the NULL byte)
A NULL string is just the pointer.

Struct pointer

4 bytes for 32-bit Specman or 8 bytes for 64-bit Specman

Struct

8 bytes + the sum of the field sizes (+ padding for 64-bit Specman)
A NULL struct is just the pointer (4 bytes for 32-bit Specman or 8 bytes
for 64-bit Specman)
Note Under 64-bit Specman, padding may be added before 8-byte
entities to ensure that they will be aligned to 8 bytes.

List

The pointer to the list (4 bytes for 32-bit Specman or 8 bytes for 64-bit
Specman) + approximately 16 bytes (header) + the sum of the sizes of the
elements
Lists of scalars of size up to 16 bits are packed to the nearest power of 2
(in bits). This is often the most efficient representation.

2.3

Untyped Expressions

All e expressions have an explicit type, except for the following types of expressions:

HDL objects, such as 'top.w_en'

pack() expressions, such as pack(packing.low, 5)

bit concatenations, such as %{slb1, slb2};

The default type of HDL objects is 32-bit uint, while pack() expressions and bit concatenations have a
default type of list of bit. However, because of implicit packing and unpacking, Specman can convert
these expressions to the required data type and bit size in certain contexts.

When an untyped expression is assigned to a scalar or list of scalars, it is implicitly unpacked and
converted to the same type and bit size as the expression on the left-hand side.

Specman e Language Reference


1999-2015

166

Product Version 15.1


All Rights Reserved.

The pack expression shown below, for example, is evaluated as 0x04, taking the type and bit size of
j.
var j:int(bits:8);
j = pack(packing.low, 4);

Note Implicit unpacking is not supported for strings, structs, or lists of non-scalar types. As a
result, the following causes a load-time error if i is a string, a struct, or a list of a non-scalar type:
i = pack(packing.low, 5);

When a scalar or list of scalars is assigned to an untyped expression, it is implicitly packed before it
is assigned.
In the following example, the value of j, 0x4, is implicitly packed and converted to the size of
'top.a' before the value is driven:
'top.a' = j;

Note Implicit packing is not supported for strings, structs, or lists of non-scalar types. As a result,
the assignment above would cause a load-time error if j were a string, a struct, or a list of a
non-scalar type.

When the untyped expression is the operand of any binary operator (+, -, *, /,%), the expression is
assumed to be a numeric type. Specman determines the precision of the operation based on the
expected type and the type of the operands. See Precision Rules for Numeric Operations on page
176 for more information.
Both 'top.a' and pack(packing.low, -4) are handled as numeric types.
print ('top.a' + pack(packing.low, 4) == 0);

When a pack() expression includes the parameter or the return value of a method call, the expression
takes the type and size as specified in the method declaration.
The pack() expression pack(packing.low, data) generates a list of bit that is implicitly unpacked
into the required type list of byte as defined in the declaration of the send_data() method.
extend sys {
data[10]:list of byte;
send_data(d: list of byte) is {
...
};
run() is also {
send_data(pack(packing.low, data));
};
};

Note The method parameter or return value in the pack expression must be a scalar type or a list
of scalar type. For example, the following results in a load-time error:
struct instruction {
Specman e Language Reference
1999-2015

167
.

Product Version 15.1


All Rights Reserved.

%opcode
%operand
%address

: uint (bits : 3);


: uint (bits : 5);
: uint (bits : 8);

};
extend sys {
instr: instruction;
send_instr(i: instruction) is {
...
};
run() is also {;
send_instr(pack(packing.low, 5)); --load-time error
};
};

When an untyped expression appears in one of the following contexts, it is treated as a Boolean
expression:
if (untyped_exp) then {..}
while (untyped_exp) do {..}
check that (untyped_exp)
not untyped_exp
rise(untyped_exp), fall(untyped_exp), true(untyped_exp)

When Specman cannot determine the type and bit size from the context, it automatically casts the
expression according to the following rules.

The default type of an HDL signal is an unsigned integer.

The default type of a pack expression and a bit concatenation expression is a list of bit.

If no bit width specification is detected, the default width is 32 bits.

One common context where Specman cannot determine the type of an expression is a print statement.
In the following example, the value displayed by the first print statement is 0xaaaaffff. The value
displayed by the second print statement is 0xffffaaaaffff.
'top.a' = 48'0xffffaaaaffff;
print 'top.a';
var tmp: uint(bits: 48) = 'top.a';
print tmp;

When expressions are untyped, an implicit pack/unpack is performed according to the expected type.

See Also

Implicit Packing and Unpacking on page 1057

Specman e Language Reference


1999-2015

168

Product Version 15.1


All Rights Reserved.

2.4

Assignment Rules

Assignment rules define what is a legal assignment and how values are assigned to entities. The
following sections describe various aspects of assignments:

What Is an Assignment? on page 169

Assignments That Create Identical References on page 170

Assignment of Numeric Types on page 171

Assignment of Boolean Types on page 172

Assignment of Enumerated Types on page 172

Assignment of Structs on page 173

Assignment of Strings on page 174

Assignment of Lists on page 175

Assignment of Sets on page 175

See Also

Untyped Expressions on page 166

Precision Rules for Numeric Operations on page 176

Automatic Type Casting on page 180

2.4.1

What Is an Assignment?

There are several legal ways to assign values:

Assignment actions
Return actions
Parameter passing
Variable declaration

Here is an example of an assignment action, where a value is explicitly assigned to a variable x and to
a field sys.x.
extend sys{
x: int;
m() is {
sys.x = '~/top/address';
var x: int;
x = sys.x + 1;
};
};

Specman e Language Reference


1999-2015

169
.

Product Version 15.1


All Rights Reserved.

Heres an example of a return action, which implicitly assigns a value to the result variable:
extend sys {
n(): int (bits: 64) is {
return 1;
};
};

Heres an example of assigning a value (6) to a method parameter (i):


extend sys {
k(i: int) @sys.any is {
wait [i] * cycle;
};
run() is also {
start k(6);
};
};

Heres an example of how variables are assigned during declaration:


extend sys {
b() is {
var x: int = 5;
var y:= "ABC";
};
};

Note

2.4.2

You cannot assign values to fields during declaration in this same manner.

Assignments That Create Identical References

Struct and list types are assigned by reference. In other words, after the assignment takes place, the
variable on the left side refers to the same instance that was referred to by the expression on the right
side. For example, consider the code:
data1: list of byte;
data2: list of byte;
run() is also {
data2 = data1;
data1[0] = 0;
};

Specman e Language Reference


1999-2015

170

Product Version 15.1


All Rights Reserved.

After generation, data1 and data2 refer to different lists. However, after the data2=data1 assignment,
both lists refer to the same list instance. Therefore changing the data1[0] value also changes the data2[0]
value immediately.

2.4.3

Assignment of Numeric Types

Any numeric type (for example, uint, int, or one of their subtypes) can be assigned with any other
numeric type. Untyped expressions, such as HDL objects, can also appear in assignments of numeric
types. See Untyped Expressions on page 166 for more information.
extend sys {
!x1: int;
x2: uint (bits: 3);
!x3: int [10..100];
post_generate() is also{
x1 = x2;
x3 = x1;
var x: int (bits: 48) = x3;
};
};

Notes

Automatic casting is performed when a numeric type is assigned to a different numeric type, and
automatic extension or truncation is performed if the types have different bit size. For more
information, see Automatic Type Casting on page 180 for more information.
When a numeric type is defined with a subrangefor example, type n: int [1..5]the subrange
defines the legal values that can be generated for that type. Any numeric value, however, can be
assigned to that type.
For example, the following code is legal (does not generate an error message), even though it may
not be the intended usage:
type n: int [1..5]
extend sys {
run() is also {
var x: n = 10;
};
};

See Also

Precision Rules for Numeric Operations on page 176 provides information on how Specman
determines precision for operations involving numeric types.

Specman e Language Reference


1999-2015

171
.

Product Version 15.1


All Rights Reserved.

type scalar subtype on page 185

type sized scalar on page 187

What Is an Assignment? on page 169

2.4.4

Assignment of Boolean Types

A Boolean type can only be assigned with another Boolean type.


var x: bool;
x = 'top.a' >= 16;

See Also

as_a() on page 194

What Is an Assignment? on page 169

2.4.5

Assignment of Enumerated Types

An enumerated type can be assigned with that same type, or with its scalar subtype. (The scalar subtype
differs only in range or bit size from the base type.)
The example below shows:

An assignment of the same type:


var x: color = blue;

An assignment of a scalar subtype:


var y: color2 = x;

Example
type color: [red,green,blue];
type color2: color (bits: 2);
extend sys {
m() is {
var x: color = blue;
var y: color2 = x;
};
};

Specman e Language Reference


1999-2015

172

Product Version 15.1


All Rights Reserved.

Notes

Be aware that Specman does not issue an error if you assign a value to an enumerated type that is
not within its specified subrange, but is within the range of another enumerated type on which the
first one is based (or vice versa).
For example, Specman does not issue a load error message for the following code:
type color1: [red,green,blue];
type color2: color1;
extend color2: [brown]
...
var c: color1;
c = brown; // no error message, even though brown is not
// within the defined range for color1

Note that his happens only when one of the enumerated types is based on the other. For example, the
following code does result in a load error:
type color1: [red,green,blue];
type color2: [brown, grey];
...
var c: color1;
c = brown; // results in load error message

Be careful to avoid the first scenario (where no error message is emitted) if this is not the intended
usage for your environment.

For information regarding limitations for casting of enumerated types, see as_a() on page 194 and
Type Conversion Between Scalars and Lists of Scalars on page 202.

See Also

What Is an Assignment? on page 169

type enumerated scalar on page 183

Casting of Enumerated Types in Comparisons on page 148

2.4.6

Assignment of Structs

An entity of type struct can be assigned with a struct of that same type or with one of its subtypes. The
following example shows:

A same type assignment:

An assignment of a subtype (Ether_8023 packet):

p2 = p1;
set_cell(p);
Specman e Language Reference
1999-2015

173
.

Product Version 15.1


All Rights Reserved.

An assignment of a derived struct (cell_8023):


p.cell = new cell_8023;

Example
type packet_kind: [Ether, Ether_8023];
struct cell {};
struct cell_8023 like cell {};
struct packet {
packet_kind;
!cell: cell;
};
extend sys {
p1: packet;
!p2: packet;
!p3: packet;
post_generate() is also {
p2 = p1;
var p: Ether_8023 packet;
gen p;
set_cell(p);
};
set_cell(p: packet) is {
p.cell = new cell_8023;
};
};

Although you can assign a subtype to its parent struct without any explicit casting as shown above, to
perform the reverse assignment (assign a parent struct to one of its subtypes), you must use the .as_a()
method. See as_a() on page 194 for an example of how to do this.

2.4.7

Assignment of Strings

A string can be assigned only with strings, as shown below.


extend sys {
m(): string is {
return "aaa"; // assignment of a string
};
};

Specman e Language Reference


1999-2015

174

Product Version 15.1


All Rights Reserved.

2.4.8

Assignment of Lists

An entity of type list can be assigned only with a list of the same type. In the following example, the
assignments are legal because all lists are lists of integers.
extend sys {
list1: list of int;
m() is {
var x: list of int = list1;
};
};

The following example shows the same concept with a multi-dimensional list:
extend sys {
run() is also {
var l_3dim: list of list of list of int = \
{ {{1;2};{3}}; {{4};{5}};{{6;7};{7;8}};{{9};{0}}};
var l_2dim: list of list of int = l_3dim[2];
};
};

However, an assignment such as var y: list of int (bits: 16) = list1; would be an error, because list1
not the same list type as y. y has a size modifier, so it is a subtype of list1. You can use the .as_a()
method to cast between lists and their subtypes.

See Also

List Equality and Assignment in Specman Generation User Guide

Constraining Lists in Specman Generation User Guide

2.4.9

Assignment of Sets

Sets can only be assigned with set.


!addresses: set;
get_addresses(): set is {
result = addresses; // assignment of a set
};
set_addresses(s: set) is {
addresses = s; // assignment of a set
};

Specman e Language Reference


1999-2015

175
.

Product Version 15.1


All Rights Reserved.

Note The value of a variable or a field of set type can change only if it is explicitly assigned (much
like with primitive types).

2.5

Precision Rules for Numeric Operations

For precision rules, there are two types of numeric expressions in e:

Context-independent expressions, where the precision of the operation (bit width) and numeric type
(signed or unsigned) depend only on the types of the operands
Context-dependent expressions, where the precision of the operation and the numeric type depend
on the precision and numeric type of other expressions involved in the operation (the context), as
well as the types of the operands

A numeric operation in e is performed in one of three possible combinations of precision and numeric
type:

Signed 32-bit integer (int)

Unsigned 32-bit integer (uint)

Signed 64-bit integer (longint)

Unsigned 64-bit integer (longuint)

Infinite signed integer (int (bits: *))

The e language has rules for:

Determining the context of an expression

Deciding precision, and performing data conversion and sign extension

The following sections describe these rules and give an example of how these rules are applied:

Determining the Context of an Expression on page 177

Deciding Precision and Performing Data Conversion and Sign Extension on page 178

Example Application of Precision Rules on page 179

See Also

Operator Precedence on page 68

Specman e Language Reference


1999-2015

176

Product Version 15.1


All Rights Reserved.

2.5.1

Determining the Context of an Expression

The rules for defining the context of an expression are applied in the following order:
1.

In an assignment (lhs = rhs), the right-hand side (rhs) expression inherits the context of the left-hand
side (lhs) expression.

2.

A sub-expression inherits the context of its enclosing expression.

3.

In a binary-operator expression (lho OP rho), the right-hand operand (rho) inherits context from the
left-hand operand (lho), as well as from the enclosing expression.

Table 2-5 summarizes context inheritance for each type of operator that can be used in numeric

expressions.
Table 2-5

Summary of Context Inheritance in Numeric Operations

Operator

Function

Context

*/%+< <= > >=


== !=
=== !==
&|^

Arithmetic, comparison,
equality, and bit-wise
Boolean

The right-hand operand inherits context from the


left-hand operand (lho), as well as from the enclosing
expression. lho inherits only from the enclosing
expression.

~!
unary + -

Bitwise not, Boolean not,


unary plus, minus

The operand inherits context from the enclosing


expression.

[ ]

List indexing

The list index is context independent.

[ .. ]

List slicing

The indices of the slice are context independent.

[:]

Bit slicing

The indices of the slice are context independent.

f(...)

Method or routine call

The context of a parameter to a method is the type and


bit width of the formal parameter.

{...; ...}

List concatenation

Context is passed from the lhs of the assignment, but


not from left to right between the list members.

%{..., ...}

Bit concatenation

The elements of the concatenation are context


independent.

>>, <<

Shift

Context is passed from the enclosing expression to the


left operand. The context of the right operand is always
32-bit uint.

Specman e Language Reference


1999-2015

177
.

Product Version 15.1


All Rights Reserved.

Table 2-5

Summary of Context Inheritance in Numeric Operations

Operator

Function

Context

lho in [i..j]

Set literal operator

All three operands are context independent. (The range


specifiers i and j must be constant.)

&&, ||

Boolean

All operands are context independent.

a?b:c

Conditional operator

a is context independent, b inherits the context from the


enclosing expression, c inherits context from b as well
as from the enclosing expression

.as_a()

Casting

The operand is context independent.

abs(), odd()
even()

Arithmetic routine

The parameter is context independent.

min(), max()

Arithmetic routine

The second parameter inherits context from the first


parameter as well as from the enclosing expression. The
first parameter inherits only from the enclosing
expression.

ilog2(),
ilog10(),
isqrt()

Arithmetic routine

The context of the parameter is always 32-bit uint.

ipow()

Arithmetic routine

Both parameters inherit the context of the enclosing


expression, but the second parameter does not inherit
context from the first.

2.5.2

Deciding Precision and Performing Data Conversion


and Sign Extension

The rules for deciding precision, performing data conversion and sign extension are as follows:

Determine the context of the expression. The context may be comprised of up to two types.

If all types involved in an expression and its context are 32 bits in width or less:

The operation is performed in 32 bits.

If any of the types is unsigned, the operation is performed with unsigned integers.
Note Decimal constants are treated as signed integers, whether they are negative or not. All
other constants are treated as unsigned integers unless preceded by a hyphen.

Each operand is automatically cast, if necessary, to the required type.

Specman e Language Reference


1999-2015

178

Product Version 15.1


All Rights Reserved.

Note Casting of small negative numbers (signed integers) to unsigned integers produces
large positive numbers.

If types involved in an expression and its context are 64-bit longint or longuint, and others are 32
bits in width or less:

The operation is performed in 64 bits.

If longuint is involved, the operation is performed with unsigned integers.

Each operand is automatically cast, if necessary, to the required type.

If any of the types (other than longint or longuint) is greater than 32 bits:

The operation is performed in infinite precision (int (bits:*))


Each operand is zero-extended, if it is unsigned, or sign-extended, if it is signed, to infinite
precision.

If any of the types is a real type, then the operation is done in real precision, and all objects should
first be converted according to the rules described above.

2.5.3

Example Application of Precision Rules

Given the following assignment:


sum: int;
exp1: int (bytes:2);
exp2: uint (bits:4);
exp3: int (bits:4);
sum = exp1 + exp2 * exp3;

1.

The precision of the multiplication operation (exp2 * exp3) is based on the four types involved here:

The inherited context of the lhs expression (int)

The inherited context of the lho (int (bytes:2))

The type of exp2 (4-bit uint)

The type of exp3 (4-bit int)

Because one of these four types is unsigned, the multiplication is done in 32-bit unsigned integer.
Both exp2 and exp3 are converted to 32-bit uint and the multiplication operation is performed.
2.

The precision of the addition operation is based on the three types involved here:

The inherited context of the lhs expression (int)

The type of exp1 (int (bytes:2))

Specman e Language Reference


1999-2015

179
.

Product Version 15.1


All Rights Reserved.

The type of (exp2 * exp3) (uint)

Because one of these types is unsigned, the addition is done in 32-bit unsigned integer. exp1 is
converted to 32-bit uint and the addition operation is performed.
3.

For the assignment operation, the result of the addition operation is converted to 32-bit int and
assigned to sum.

See Also

Untyped Expressions on page 166

Assignment Rules on page 169

Automatic Type Casting on page 180

2.6

Automatic Type Casting

During assignment of a type to a different but compatible type, automatic type casting is performed in
the following contexts:

Numeric expressions (unsigned and signed integers) of any size are automatically type cast upon
assignment to different numeric types. For example:
var x: uint;
var y: int;
x = y;

Untyped expressions are automatically cast on assignment. See Untyped Expressions on page 166
for more information.
var j: uint = 0xff;
'top.a' = j;

Sized scalars are automatically type cast to differently sized scalars of the same type.
type color: [red,green,blue];
type color2: color (bits: 2);
var x: color = blue;
var y: color2 = x;

real types are automatically cast to the other numeric types.


See Conversion Between Real and Numeric Types on page 162

Specman automatically casts struct subtypes to their base struct type.


type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
size: int [0..1k];

Specman e Language Reference


1999-2015

180

Product Version 15.1


All Rights Reserved.

data[size]: list of byte;


show() is undefined; // To be defined by children
};
extend Ethernet packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};
extend sys {
m() is {
var epkt: Ethernet packet = new;
var pkt: packet = epkt;
};
};

There are three important ramifications to automatic type casting:


1.

If the two types differ in bit size, then the assigned value is extended or truncated to the required bit
size. See Example 1 on page 181.

2.

Casting of small negative numbers (signed integers) to unsigned integers produces large positive
numbers. See Example 2 on page 182.

3.

There is no automatic casting to a reference parameter. See Parameter Passing in Methods in


Creating e Testbenches for more information.

Example 1
In the following example, x is a 32-bit signed integer, y is a 48-bit unsigned integer, and z is a
3-bit signed integer. Assigning x to y extends x to 48 bits. Assigning x to z chops x to 3
bits.
extend sys {
m() is {
var x: int = -1;
var y: int (bits: 48) = x;
var z: int (bits: 3) = x;
print y,z;
};
};

Result
Calling sys.m() results in:
y = 0xffffffffffff
z = 0x7

Specman e Language Reference


1999-2015

181
.

Product Version 15.1


All Rights Reserved.

Example 2
m() is {
var x: int = -1;
var y: uint = MAX_UINT;
var z: uint = 1;
print x == y;
print x > z;
};

Result
The int value x (0xffffffff) is automatically cast to uint and becomes MAX_UINT. As a result, the
print statements display the following:
x == y = TRUE
x > z = TRUE

See Also

If you are working with constraints, see Understanding Semantics Used in Constraints Versus
Semantics Used in Procedural Code in Specman Generation User Guide

as_a() on page 194

Untyped Expressions on page 166

Assignment Rules on page 169

Precision Rules for Numeric Operations on page 176

2.7

Defining and Extending Scalar Types

You can use the following constructs to define and extend scalar types:

type enumerated scalar on page 183

type scalar subtype on page 185

type sized scalar on page 187

extend type on page 189

Specman e Language Reference


1999-2015

182

Product Version 15.1


All Rights Reserved.

2.7.1

type enumerated scalar

Purpose
Define an enumerated scalar type

Category
Statement

Syntax
type enum-type-name: [[name[=exp], ...]] [(bits | bytes: width-exp)]
Syntax Example
type PacketType :[ rx = 1, tx, ctrl ];

Parameters
enum-type-name

A legal e name. The name must be different from any other predefined or
enumerated type name because the namespace for types is global.

name

A legal e name. Each name must be unique within the type.

exp

A unique 32-bit constant expression. Names or name-value pairs can appear


in any order. By default, the first name in the list is assigned the integer
value zero. Subsequent names are assigned values based upon the maximum
value of the previously defined enumerated items + 1.

width-exp

A positive constant expression. The valid range of values for sized


enumerated scalar types is limited to the range 1 to 2**n - 1, where n is the
number of bits.

Description
Defines an enumerated scalar type having the name you specify and consisting of a set of names or
name-value pairs. If no values are specified, the names get corresponding numerical values starting with
0 for the first name, and casting can be done between the names and the numerical values.
Enumerated Scalar Types on page 145 contains more detail about and additional examples of

enumerated types.

Specman e Language Reference


1999-2015

183
.

Product Version 15.1


All Rights Reserved.

Example 1
This is a simple example of the basic syntax.
type PacketType :[ rx, tx, ctrl ];
struct packet {
kind :PacketType;
do_print() is {
if kind == ctrl {
out("This is a control packet.");
};
};
};

Example 2
This example shows how HDL variables are automatically cast to the required scalar type.
type PacketType :[ rx, tx, ctrl ];
struct packet {
kind :PacketType;
set() is {
kind = 'top.pkt_type';
};
};

Example 3
This example shows an enumerated type with a bit width:
type NetworkType :[ IP=0x0800, ARP=0x8060 ](bits:16);
struct header {
dest_address :uint(bits:48);
src_address :uint(bits:48);
type
:NetworkType;
do_print() is {
if type == IP {
out("This is an IP packet.");
};
};
Specman e Language Reference
1999-2015

184

Product Version 15.1


All Rights Reserved.

};

Example 4
This example shows how to type cast between an enumerated type and an unsigned integer.
type signal_number: [signal_0, signal_1, signal_2, signal_3];
struct signal {
cast_1() is {
var temp_val: uint = 3;
var signal_name: signal_number = temp_val.as_a(signal_number);
print signal_name;
};
cast_2() is {
var temp_enum: signal_number = signal_0;
var signal_value: uint = temp_enum.as_a(uint);
print signal_value;
};
};

See Also

Assignment of Enumerated Types on page 172

type scalar subtype on page 185

extend type on page 189

as_a() on page 194

2.7.2

type scalar subtype

Purpose
Define a scalar subtype

Category
Statement

Specman e Language Reference


1999-2015

185
.

Product Version 15.1


All Rights Reserved.

Syntax
type scalar-subtype-name: scalar-type [range, ...]
Syntax Example
type size: int [8, 16];

Parameters
scalar-subtype-name

A unique e name.

scalar-type

Any previously defined enumerated scalar type, any of the predefined


scalar types (other than longint or longuint), including int, uint, bool, bit,
byte, or time, or any previously defined scalar subtype.

range

A constant expression or two constant expressions separated by two dots.


All constant expressions must resolve to legal values of the named type.

Description
Defines a subtype of a scalar type by restricting the legal values that can be generated for this subtype to
the specified range.

Notes

The default value for variables or fields of this type size is zero, the default for all integers.
The range affects generated values, not necessarily assigned values. For more information, see
Assignment of Numeric Types on page 171 and Assignment of Enumerated Types on page 172.

Example 1
The integer subtype defined below includes all non-negative integers except 4,5, and 7.
type medium: uint [0..3,6,8..MAX_INT];

Example 2
The following example defines the inst type, which has six legal instruction values, and the subtype
mem_inst, which has only the values related to memory.
type inst: [add, sub, mul, div, load, store];
type mem_inst: inst [load..store];
Specman e Language Reference
1999-2015

186

Product Version 15.1


All Rights Reserved.

Example 3
You can omit the range list, thus renaming the full range. The first example below gives the name
my_int to the full range of integers. The second example gives the name true_or_false to the full
range of the Boolean type.
type my_int: int;
type true_or_false: bool;

See Also

Scalar Types on page 138

type enumerated scalar on page 183

type sized scalar on page 187

2.7.3

type sized scalar

Purpose
Define a sized scalar

Category
Statement

Syntax
type sized-scalar-name: type (bits | bytes: exp)
Syntax Example
type word
:uint(bits:16);
type address :uint(bytes:2);

Parameters
sized-scalar-name

A unique e name.

Specman e Language Reference


1999-2015

187
.

Product Version 15.1


All Rights Reserved.

type

Any previously defined enumerated type or any of the predefined scalar


types (other than longint or longuint), including int, uint, bool, or time.

exp

A positive constant expression. The valid range of values for sized scalars is
limited to the range 1 to 2n - 1, where n is the number of bits.

Description
Defines a scalar type with a specified bit width. The actual bit width is exp * 1 for bits and exp * 8 for
bytes. In the example shown below, both types word and address have a bit width of 16.
type word
:uint(bits:16);
type address :uint(bytes:2);

Example
When assigning any expression into a sized scalar variable or field, the expression's value is truncated or
extended automatically to fit into the variable. An expression with more bits than the variable is chopped
down to the size of the variable. An expression with fewer bits is extended to the length of the variable.
The added upper bits are filled with zero if the expression is unsigned, or with the sign bit (zero or one)
if it is a signed expression.
Here is an example of assigning an expression where the expression's value is truncated:
type SmallAddressType :uint(bits:2);
extend sys {
chop_expression() is {
var small_address :SmallAddressType;
small_address = 0x2 * 8;
out("small_address: ", small_address);
};
run() is also {
chop_expression();
};
};

See Also

type enumerated scalar on page 183

type scalar subtype on page 185

Specman e Language Reference


1999-2015

188

Product Version 15.1


All Rights Reserved.

extend type on page 189

Assignment Rules on page 169

Precision Rules for Numeric Operations on page 176

2.7.4

extend type

Purpose
Extend an enumerated scalar type

Category
Statement

Syntax
extend enum-type: [name[= exp], ...]
Syntax Example
type PacketType :[ rx, tx, ctrl ];
extend PacketType :[ status ];

Parameters
enum-type

Any previously defined enumerated type.

name

A legal e name. Each name must be unique within the type.

exp

A unique 32-bit constant expression. Names or name-value pairs can appear in


any order. By default, the first name in the list is assigned the integer value
zero. Subsequent names are assigned values based upon the maximum value of
the previously defined enumerated items + 1.

Description
Extends the specified enumerated scalar type to include the names or name-value pairs you specify.
Note The range extension affects generated values, not necessarily assigned values. For more
information, see Assignment of Enumerated Types on page 172.

Specman e Language Reference


1999-2015

189
.

Product Version 15.1


All Rights Reserved.

Example 1
This is an example of the basic syntax.
type command

:[ ADD=0x00, SUB=0x02, AND=0x04,


XOR=0x06, UDEF=0xFF ] (bits: 8);

extend command :[ ADDI=0x01, SUBI=0x03,


ANDI=0x05, XORI=0x07 ];

Example 2
A common use of type extension is defining a protocol type and extending it as new protocols are added
to the test environment. For example, you can define a packet header without having to know what
specific network protocols are supported by the packet:
type NetworkType :[ ](bits:16);
struct header {
dest_address :uint(bits:48);
src_address :uint(bits:48);
type
:NetworkType;
};

As protocols are gradually added to the test environment, the new protocol type can be added without
changes to the original code:
extend NetworkType :[ ARP=0x8060 ];

Then again for more protocols:


extend NetworkType :[ IP=0x0800 ];

See Also

type enumerated scalar on page 183

type scalar subtype on page 185

type sized scalar on page 187

2.8

Referring to Types in Generic Code

Some generic code, such as a macro, might require mentioning a type name that is dependent on the
specific context (e.g., the type of some particular local variable or expression, recognizable in that
context). For example:
Specman e Language Reference
1999-2015

190

Product Version 15.1


All Rights Reserved.

a macro may need to declare a variable of type similar to the type of one of its <exp> syntactic
arguments.
a <struct_member> macro may need to refer to its context struct type.

The following operator can be used to reference types in generic code:

typeof() / typeof_item() on page 191

2.8.1

typeof() / typeof_item()

Purpose
References types in generic code

Category
Type

Syntax
typeof(expression)
typeof_item(list-expression)
Syntax Example
var x: typeof(y);

Parameters
expression

Any e expression that is valid in the current context.

list-expression

An e expression of a list type, that is valid in the current context.

Description
The typeof() operator can be used wherever a type name is expected, including in a variable or a field
declaration, a parameter or the result type of a method declaration, and so on. It is replaced by the actual
type of the expression.
The typeof_item() operator can be used in the same way. However, it expects an expression of a list type
only, and it is replaced by the actual list element type.
Specman e Language Reference
1999-2015

191
.

Product Version 15.1


All Rights Reserved.

The expression itself can be any e expression (for typeof() ) or any e expression of a list type (for
typeof_item() ), valid in the current context, whose type can be determined. In particular,

if used in a procedural context (for example, inside a method), expression can be or contain any local
variables;
if used inside a struct definition (not necessarily procedural context, for example, in a field or a cover
item declaration), expression can be or contain me to refer to the context struct; and so on.

The expression is never actually executed or evaluated, neither at compilation time nor at run time. Its
sole purpose is to determine its type, which is done at compilation time, and it is completely static and
does not depend on any actual value or object instance at run time.
Although typeof() / typeof_item() can be used anywhere, in practice it is mainly useful inside generic
(parameterized) code (although some users might also find it convenient to use in regular code), such as
in the replacement code of a define-as or define-as-computed macro.

Example 1
In this example, we define a <struct_member> macro that declares a field with an initial value, without
explicitly specifying the field type. By using typeof(), we are able to determine the actual type of the
field to be declared, according to the type of the given expression.
define <init_field'struct_member> "<name>[ ]:=[ ]<exp>" as {
<name>: typeof(<exp>);
init() is also {
<name> = <exp>;
};
};

The above macro can be used, for example, as follows:


extend packet_s {
addr := 0xffff;
value1 := value * 2;
};

-- assuming value is a previously declared field

Example 2
In this example, we define a pseudo-method called one_field_copy(), that creates a new object of the
same struct type as the given object, and copies one specific field from the given struct to the new one.
define <one_field_copy'exp>
"<orig'exp>[ ].[ ]one_field_copy[ ]\(<field'name>\)" as {
new typeof(<orig'exp>) with {
it.<field'name> = <orig'exp>.<field'name>;
Specman e Language Reference
1999-2015

192

Product Version 15.1


All Rights Reserved.

};
};

The above pseudo-method can be used, for example, as follows:


struct packet_s {
data: int;
addr: uint;
};
extend sys {
p: packet_s;
!p1: packet_s;
run() is also {
p1 = p.one_field_copy(data);
};
};

Example 3
In this example, we define a macro that adds a field of the same type as the context struct, and a getter
method for that field. It can be useful for implementing linked lists.
define <linked_list_pointer'struct_member> "linked_list_pointer" as {
private !next_struct: typeof(me);
get_next(): typeof(me) is {
return next_struct;
};
};

Example 4
In this example, the following macro uses typeof_item(). It assumes that the context struct already has
a field by the given name of a list type, adds a new field of the list element type, and adds a constraint
for the new field to be contained in the list.
define <item'struct_member> "item <list_field'name>" as {
<list_field'name>_item: typeof_item(<list_field'name>);
keep <list_field'name>_item in <list_field'name>;
};

Specman e Language Reference


1999-2015

193
.

Product Version 15.1


All Rights Reserved.

2.9

Converting from One Data Type to Another

The as_a() expression is used to convert an expression from one data type to another. Information about
how different types are converted, such as strings to scalars or lists of scalars, is contained in Table 2-6
on page 202 and Table 2-7 on page 205.

2.9.1

as_a()

Purpose
Casting operator

Category
Expression

Syntax
exp.as_a(type: type name): type
Syntax Example
print (b).as_a(uint);

Parameters
exp

Any e expression.

type

Any legal e type.

Description
Returns the expression, converted into the specified type. Although Specman performs some casting
automatically (see Automatic Type Casting on page 180), explicit casting is required in some cases
when making assignments between different but compatible types.
Note No checking is performed to make sure the value is valid when casting from a numeric or
Boolean type to an enumerated type or when casting between enumerated types.

See Also

Type Conversion Between Scalars and Lists of Scalars on page 202

Specman e Language Reference


1999-2015

194

Product Version 15.1


All Rights Reserved.

Type Conversion Between Strings and Scalars or Lists of Scalars on page 204

Type Conversion Between Structs, Struct Subtypes, and Lists of Structs on page 206

Type Conversion Between Simple Lists and Keyed Lists on page 207

Type Conversion Between Multi-Dimensional Lists on page 208

Type Conversion Between Lists of Numeric and Set on page 208

Casting of Enumerated Types in Comparisons on page 148

Conversion Between Real and Numeric Types on page 162

Conversions Between Real and Non-Numeric Types on page 162

Automatic Type Casting on page 180

is [not] a on page 123

2.9.1.1

as_a Examples

Example 1
In this example, the most significant bits of the 32-bit variable i are truncated when i is printed as a
16-bit variable. When i is printed as a 64-bit variable, it is sign-extended to fit.
extend sys {
m() is {
var i : int = 0xffff000f;
print (i).as_a(int(bits:16)) using radix=HEX;
print (i).as_a(int(bits:64)) using radix=HEX;
};
};

Result
cmd-prompt> sys.m()
(i).as_a(int(bits:16)) = 0x000f
(i).as_a(int(bits:64)) = 0xffffffffffff000f

Example 2
No checking is performed when c, a variable of type color, is assigned a value outside its range.
However, a message is issued when the c is accessed by the print statement.
type color: [red=2, blue=0, yellow=1];
extend sys{
m() is {
var c : color = blue;
var i : int = 2;
Specman e Language Reference
1999-2015

195
.

Product Version 15.1


All Rights Reserved.

var u : uint = 0x74786574;


print (i).as_a(color);
print (c).as_a(int);
c = u.as_a(color);
--no checking
print c;
--message issued
};
};

Result
cmd-prompt> sys.m()
(i).as_a(color) = red
(c).as_a(int) = 0x0
c = (Bad enum value for 'color': 1954047348)

Example 3
You can use the as_a() method to convert a Boolean type to a numeric or an enumerated type or from
one of those types to a Boolean.
type color: [red=2, blue=0, yellow=1];
extend sys{
m() is {
var c : color = blue;
var i : int = 2;
var s : string = "hello";
print (i).as_a(bool);
print (c).as_a(bool);
};
};

Result
cmd-prompt> sys.m()
(i).as_a(bool) = TRUE
(c).as_a(bool) = FALSE

Example 4
You can cast between numeric types and strings with as_a(), but no ASCII conversion is performed.
This example shows how to get ASCII conversion using unpack() and the bit concatenation
operator %{}.
extend sys{
m() is {
var i : int = 65;

Specman e Language Reference


1999-2015

196

Product Version 15.1


All Rights Reserved.

var s1 : string;
var s2 : string = "B";
print (i).as_a(string);
unpack(packing.low, %{8'b0,i}, s1);
print s1;
--print (s2).as_a(int); --run-time error;
--B is not a valid integer
var i_proper : byte;
i_proper = (%{s2})[1];
print i_proper;
};
};

Result
cmd-prompt> sys.m()
(i).as_a(string) = "65"
s1 = "A"
i_proper = 66

Example 5
You can cast between lists of numerics and strings with as_a(). As shown in the first print statement,
each character in the string is converted to its numeric value and assigned to a separate element in the
list. As shown in the second to last print statement, using pack() to convert a string concatenates the
numeric values of the characters before assigning them to the list.
extend sys {
m() is {
var s: string;
s = "hello";
var lint: list of int;
lint = s.as_a(list of int);
print lint;
print lint.as_a(string);
var lint2: list of int;
lint2 = pack(packing.low, s);
print lint2 using bin;
print lint using bin;
};
};

Result
cmd-prompt> sys.m()
lint =

Specman e Language Reference


1999-2015

197
.

Product Version 15.1


All Rights Reserved.

0.
104
1.
101
2.
108
3.
108
4.
111
lint.as_a(string) = "hello"
lint2 =
0.
0b1101100011011000110010101101000
1.
0b1101111
lint =
0.
0b1101000
1.
0b1100101
2.
0b1101100
3.
0b1101100
4.
0b1101111

Example 6
The print pkt.as_a(foreign packet) action below results in pkt.as_a(foreign packet) = NULL
because pkt is of type Ethernet packet.
The print pkt.e_field action in this example results in a compile-time error because the declared type
of pkt does not have a field e_field. However, the print pkt.as_a(Ethernet packet).e_field action
prints the value of the field.
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
show() is undefined; // To be defined by children
};
extend Ethernet packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};
extend sys {
m() is {
var epkt: Ethernet packet = new;
var pkt: packet = epkt;
print pkt.as_a(foreign packet);
-print pkt.e_field;
//compile-time error
print pkt.as_a(Ethernet packet).e_field;
print pkt.size;
};
};

Specman e Language Reference


1999-2015

198

Product Version 15.1


All Rights Reserved.

Result
cmd-prompt> sys.m()
pkt.as_a(foreign packet) = (NULL)
pkt.as_a(Ethernet packet).e_field = 0
pkt.size = 0

Example 7
The as_a() pseudo-method, when applied to a scalar list, creates a new list whose size is the same as the
original size and then casts each element separately.
To pass a list of integer(bits: 4) as a parameter to a method that requires a list of integers, you can use
explicit casting, as follows:
struct dtypes {
increment_list (cnt: list of int) is {
for each in cnt {
cnt[index] = cnt[index] + 1;
};
};
};
extend sys {
di:dtypes;
m() is {
var small_list: list of int (bits: 5) = {3;5;7;9};
var big_list: list of int = {0;0;0;0;};
big_list = small_list.as_a(list of int);
di.increment_list(big_list);
print big_list;
};
};

Result
The print statement gives the following results:
big_list =
0.
4
1.
6
2.
8
3.
10

Specman e Language Reference


1999-2015

199
.

Product Version 15.1


All Rights Reserved.

Example 8
When the as_a() operator is applied to a list of structs, the list items for which the casting failed are
omitted from the list.
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
show() is undefined; // To be defined by children
};
extend Ethernet packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};
extend sys {
packets[5]: list of packet;
post_generate() is also {
print packets;
print packets.as_a(list of IEEE packet);
};
};

Result
cmd-prompt> gen
Doing setup ...
Generating the test using seed 1...
packets =
item
type
protocol
size

data

Ethernet'*

0.
packet
Ethernet
872
1.
packet
Ethernet
830
2.
packet
Ethernet
834
3.
packet
Ethernet
663
4.
packet
IEEE
213
packets.as_a(list of IEEE packet) =
item
type
protocol
size

(872
(830
(834
(663
(213

0.

(213 item*

packet

IEEE

213

item*
item*
item*
item*
item*

data

-21166003*
-21443627*
1684201428
-15262725*

Ethernet'*

Example 9
You can use as_a() to convert a string to an enumerated type. The string has to match letter by letter one
of the possible values of that type or a runtime error is issued.

Specman e Language Reference


1999-2015

200

Product Version 15.1


All Rights Reserved.

This example sets a list of items of an enumerated type to the values read from a file.
type reg_address: [UARTCTL1, UARTDATA1, UARTCTL2, UARTDATA2];
extend sys {
ctl_regs: list of reg_address;
keep ctl_regs == (each line in file \
"enum_items.txt").apply(it.as_a(reg_address));
run() is also {
print sys.ctl_regs;
};
};

enum_items.txt
UARTCTL1
UARTDATA1
UARTCTL2
UARTDATA2
UARTDATA1
UARTCTL2
UARTCTL2
UARTCTL1
UARTDATA1

Result
sys.ctl_regs =
0.
UARTCTL1
1.
UARTDATA1
2.
UARTCTL2
3.
UARTDATA2
4.
UARTDATA1
5.
UARTCTL2
6.
UARTCTL2
7.
UARTCTL1
8.
UARTDATA1

Note If the file is not accessible, you will see a runtime error with the name of the missing file. If there
is a typo in the file, you will see a runtime error message like the following:
*** Error: Enum type 'reg_address' has no item called 'UARTCTL'

Specman e Language Reference


1999-2015

201
.

Product Version 15.1


All Rights Reserved.

2.9.2

Type Conversion Between Scalars and Lists of Scalars

Numeric expressions (unsigned and signed integers) of any size are automatically type cast upon
assignment to different numeric types.
For other scalars and lists of scalars, there are a number of ways to perform type conversion, including
the as_a() method, the pack() method, the %{} bit concatenation operator and various string routines.
Table 2-6 on page 202 shows the recommended methods for converting between scalars and lists of
scalars.
In Table 2-6 on page 202, int represents int/uint of any size, including bit, byte, and any user-created
size. If a solution is specific to bit or byte, then bit or byte is explicitly stated.
int(bits:x) means x as any constant; variables cannot be used as the integer width.
The solutions assume that there is a variables declared as
var
var
var
var
var
var

int : int ;
bool : bool ;
enum : enum ;
list_of_bit : list of bit ;
list_of_byte : list of byte ;
list_of_int : list of int ;

Any conversions not explicitly shown may have to be accomplished in two stages.
Table 2-6

Type Conversion Between Scalars and Lists of Scalars

From

To

Solutions

int

list of bit

list_of_bit = int[..]

int

list of
int(bits:x)

list_of_int = %{int}
list_of_int = pack(packing.low, int)
(LSB of int goes to list[0] for either choice)

list of bit

int

int = list_of_bit[:]

int

int = pack(packing.low, list_of_int)

list of byte
list of
int(bits:x)

Specman e Language Reference


1999-2015

(Use packing.high for list in other order.)

202

Product Version 15.1


All Rights Reserved.

Table 2-6

Type Conversion Between Scalars and Lists of Scalars

From

To

Solutions

int(bits:x)

int(bits:y)

intx = inty
(Truncation or extension is automatic.)
intx.as_a(int(bits:y))

bool

int

int = bool.as_a(int)
(TRUE becomes 1, FALSE becomes 0.)

int

bool

bool = int.as_a(bool)
(0 becomes FALSE, non-0 becomes TRUE.)

int

enum

enum = int.as_a(enum)
(No checking is performed to make sure the int value is valid for the
range of the enum.)

enum

int

int = enum.as_a(int)
(Truncation is automatic.)

enum

bool

enum.as_a(bool)
(Enumerated types with an associated unsigned integer value of 0
become FALSE; those with an associated non-0 values become
TRUE. See Enumerated Scalar Types on page 145 for more
information on values associated with enumerated types.)

bool

enum

bool.as_a(enum)
(Boolean types with a value of FALSE are converted to the
enumerated type value that is associated with the unsigned integer
value of 0; those with a value of TRUE are converted to the
enumerated type value that is associated with the unsigned integer
value of 1. No checking is performed to make sure the Boolean value
is valid for the range of the enum.)

enum

enum

enum1 = enum2.as_a(enum1)
(no checking is performed to make sure the int value is valid for the
range of the enum)

Specman e Language Reference


1999-2015

203
.

Product Version 15.1


All Rights Reserved.

Table 2-6

Type Conversion Between Scalars and Lists of Scalars

From

To

Solutions

list of
int(bits:x)

list of
int(bits:y)

listx.as_a(list of int(bits:y))
(same number of items, each padded or truncated)
listy = pack(packing.low, listx)
(concatenated data, different number of items)

See Also

as_a() on page 194

2.9.3

Type Conversion Between Strings and Scalars or Lists


of Scalars

There are a number of ways to perform type conversion between strings and scalars or lists of scalars,
including the as_a() method, the pack() method, the %{} bit concatenation operator and various string
routines. Table 2-7 on page 205 shows how to convert between strings and scalars or lists of scalars.
In Table 2-7 on page 205, int represents int/uint of any size, including bit, byte, and any user-created
size. If a solution is specific to bit or byte, then bit or byte is explicitly stated.
int(bits:x) means x as any constant; variables cannot be used as the integer width.
The solutions assume that there is a variables declared as
var
var
var
var
var
var

int : int ;
list_of_byte : list of byte ;
list_of_int : list of int ;
bool : bool ;
enum : enum ;
string : string ;

Any conversions not explicitly shown may have to be accomplished in two stages.

Specman e Language Reference


1999-2015

204

Product Version 15.1


All Rights Reserved.

Table 2-7

Type Conversion Between Strings and Scalars or Lists of Scalars

From

To

ASCII
Convert?

Solutions

list of int

string

yes

list_of_int.as_a(string)

list of byte

string

(Each list item is converted to its ASCII character and


the characters are concatenated into a single string.
int[0] represents left-most character. Depending on
the value of a given list item, its corresponding ASCII
character might be printable or non-printable. If a list
items value is a non-printable ASCII character, you
will get spurious results if you try to print it.)
list of int

yes

list of byte

string

list of int

string.as_a(list of int)
(Each character in the string is converted to its
numeric value and assigned to a separate element in
the list. The left-most character becomes int[0])

yes

list_of_int = pack(packing.low, string)


list_of_int = %{string}
(The numeric values of the characters are
concatenated before assigning them to the list. Any
pack option gives same result; null byte, 00, will be
last item in list.)

string

int

yes

int = %{string}
int = pack(packing.low, string)
(Any pack option gives same result.)

int

string

yes

unpack(packing.low, %{8b0, int}, string)


(Any pack option with scalar_reorder={} gives same
result.)

Specman e Language Reference


1999-2015

205
.

Product Version 15.1


All Rights Reserved.

Table 2-7

Type Conversion Between Strings and Scalars or Lists of Scalars

From

To

ASCII
Convert?

string

int

no

Solutions
string.as_a(int)
(Converts to decimal.)
append(0b, string).as_a(int)
(Converts to binary.)
append(0x, string).as_a(int)
(Converts to hexadecimal.)

int

string

no

int.as_a(string)
(Uses the current print radix.)
append(int)
(Converts int according to current print radix.)
dec(int), hex(int), bin(int)
(Converts int according to specific radix.)

string

bool

no

bool = string.as_a(bool)
(Only TRUE and FALSE can be converted to
Boolean; all other strings return an error.)

bool

string

no

string = bool.as_a(string)

string

enum

no

enum = string.as_a(enum)

enum

string

no

string = enum.as_a(string)

See Also

as_a() on page 194

2.9.4

Type Conversion Between Structs, Struct Subtypes,


and Lists of Structs

Specman automatically casts struct subtypes to their base struct type, so, for example, you can assign a
variable of type Ethernet packet to a variable of type packet without using as_a().
You can use as_a() to cast a base struct type to one of its subtypes; if a mismatch occurs, then NULL is
assigned. For example, the print pkt.as_a(foreign packet) action results in pkt.as_a(foreign packet)
= NULL if pkt is not a foreign packet.
Specman e Language Reference
1999-2015

206

Product Version 15.1


All Rights Reserved.

When the expression to be converted is a list of structs, as_a() returns a new list of items whose type
matches the specified type parameter. If no items match the type parameter, an empty list is returned.
The list can contain items of various subtypes, but all items must have a common parent type. That is,
the specified type parameter must be a subtype of the type of the list.
Assigning a struct subtype to a base struct type does not change the declared type. Thus, you have to use
as_a() to cast the base struct type as the subtype in order to access any of the subtype-specific struct
members. See Example 6 on page 198.
Subtypes created through like inheritance exhibit the same behavior as subtypes created through when
inheritance.

See Also

as_a() on page 194

2.9.5

Type Conversion Between Simple Lists and Keyed


Lists

You can convert simple lists to keyed lists and keyed lists to simple lists. When you convert a keyed list
to a simple list, the hash key is dropped. When you convert a simple list to a keyed list, you must specify
the key.
For example, if sys.packets is a simple list of packets and you want to convert it to a keyed list where
the len field of the packet struct is the key, you can do so like this:
Specman > var pkts: list (key: len) of packet
Specman > pkts = sys.packets.as_a(list (key: len) of packet)

The as_a() method returns a copy of sys.packets, so the original sys.packets is still a simple list, not a
keyed list. Thus print pkts.key_index(130) returns the index of the item that has a len field of 130,
while print sys.packets.key_index(130) returns an error.
If a conversion between a simple list and a keyed list also involves a conversion of the type of each item,
that conversion of each item follows the standard rules. For example, it is a rule that if you use as_a() to
convert an integer to a string, no ASCII conversion is performed. Similarly, if you use as_a() to convert
a simple list of integers to a keyed list of strings, no ASCII conversion is performed:
Specman > var lk: list (key:it) of string
Specman > var l: list of int = {1;2;3;4;6;9}
Specman > lk = l.as_a(list (key:it) of string)
Specman > print lk.key_index("9")
lk.key_index("9") = 5

Specman e Language Reference


1999-2015

207
.

Product Version 15.1


All Rights Reserved.

See Also

as_a() on page 194

2.9.6

Type Conversion Between Multi-Dimensional Lists

You can convert one multi-dimensional list to another multi-dimensional list using explicit casting. The
rules for using the expression md-list1.as_a(md-list2) are as follows:

Both lists must have exactly the same number of dimensions

The basic element type for md-list1 must be convertible into the basic element type for md-list2.

Example:
<'
struct A {};
struct B like A{};
extend sys {
run() is also {
var b1: B = new;
var b2: B = new;
var lb: list of list of B = {{b1};{b2}};
var la: list of list of A = lb.as_a(list of list of A);
};
};
'>

See Also

as_a() on page 194

2.9.7

Type Conversion Between Lists of Numeric and Set

You can use explicit casting to convert between lists of numeric and set, in both directions:

numeric-list-exp.as_a(set)
The rules for using the expression numeric-list-exp.as_a(set) is fairly straight forward.
All items of the original list, and only those items, are contained in resulting set. Note that for types
with range, the legality of the values is not checked. Furthermore, no assumption are made
regarding the order of items in list, repetition, etc.

set-exp.as_a(list of numeric-type)

Specman e Language Reference


1999-2015

208

Product Version 15.1


All Rights Reserved.

The rules in the opposite direction that is, for using the expression set-exp.as_a(list of
numeric-type) are a bit more complex:

If set .size() of the set is > 1M, will result in a run-time notification.

Legality of values is not checked.

Values out of the possible range of numeric-type are numerically casted.

The list is created from lower bound to upper bound of the set, and unless numeric casting changes
some values, the resulting list is sorted. For example:
[-1..1].as_a(list of int) is {-1;0;1}
[-1..1].as_a(list of uint) is {MAX_UINT;0;1}.

It is recommended that if it is not known for sure that the set is correctly constructed correctly, you
should check it with .size() and in set_of_values() before casting, to ensure that no error or value
distortion will occur.
Example:
addresses: list of address_t;
get_address_set(): set is {
result = addresses.as_a(set);
};
set_addresses(s: set) is {
if s.size() > 100K {
error("Set ", s, " is too large");
};
addresses = s.as_a(list of address_t);
};

See Also

as_a() on page 194

2.10 Accessing All Values of a Scalar Type


2.10.1

all_values()

Purpose
Access all values of a scalar type

Specman e Language Reference


1999-2015

209
.

Product Version 15.1


All Rights Reserved.

Category
Pseudo routine

Syntax
all_values(scalar-type: type name): list of scalar type
Syntax Example
print all_values(reg_address);

Parameters
scalar-type Any legal e scalar type.

Description
Returns a list that contains all the legal generated values of the specified scalar type. When that type is
an enumerated type, the order of the items is the same as the order in which they were defined. When the
type is a numeric type, the order of the items is from the smallest to the largest.

Note
When the specified type has more than 1million legal values, this routine gives a compile time error to
alert you to possible memory abuse.

Example
type reg_address: [UARTCTL1, UARTDATA1, UARTCTL2, UARTDATA2];
extend sys {
ctl_regs: list of reg_address;
keep ctl_regs ==
all_values(reg_address).all(it.as_a(string) ~"*CTL*");
run() is also {
print sys.ctl_regs;
};
};

Result
Running the test ...
sys.ctl_regs =
Specman e Language Reference
1999-2015

210

Product Version 15.1


All Rights Reserved.

0.
1.

UARTCTL1
UARTCTL2

2.10.2

set_of_values(type) / full_set_of_values(type)

Purpose
Access the set of all values of a type

Category
Pseudo routine

Syntax
Use the following syntax to access the set of all legal values of a type:
set_of_values(scalar-type): set
Use the following syntax to access the set of all possible values of a type, legal and illegal:
full_set_of_values(scalar-type): set
Syntax Example
if v in set_of_values(address_t) {
result = TRUE;
};

Parameters
scalar-type Any legal numeric or enum type.

Description
Returns a set that contains all values of the specified type:

For set_of_values(scalar-type): set, it returns the set of all legal values, as follows:

For numerics without a range, the set contains all possible values (signed/unsigned) for the type
according to bit width.

Specman e Language Reference


1999-2015

211
.

Product Version 15.1


All Rights Reserved.

If a numeric type has a range, only values in the range are considered as legal.

For an enum type, it returns set of numeric values of all enum items of the type.

For an enum type with range, it returns set of numeric values of enum items belonging to the range

For full_set_of_values(scalar-type): set, it returns the set of all possible values, whether legal or
illegal, limited only by bit width. It also indicates if it is signed or unsigned.

Notes

Types real and int(bits:*) will give a parse-time error


Types based on int(bits:*) with a range will work with set_of_values(scalar-type), but will produce
an error with full_set_of_values(scalar-type).

Table 2-8 displays values for some types according to the particular syntax (set_of_values(scalar-type)

or full_set_of_values(scalar-type)).
Table 2-8

Table of Values for Some Types

Type

set_of_values(type)

full_set_of_values(type)

int

[MIN_INT..MAX_INT]

[MIN_INT..MAX_INT]

uint

[0..MAX_UINT]

[0..MAX_UINT]

int(bits:5)

[-16..15]

[-16..15]

uint[5..100]

[5..100]

[0..MAX_UINT]

type color:[black, gray,


white, red=5, green=6,
blue=7];

[0..2,5..7]

[0..MAX_UINT]

type bw:
color[black..white];

[0..2]

[0..MAX_UINT]

real

Parse-time error

Parse-time error

int(bits:*)

Parse-time error

Parse-time error

type T :
int(bits:*)[MIN_INT..
MAX_UINT]

[MIN_INT.. MAX_UINT]

Parse-time error

Example
!pending_addresses: list of address_t;
!bad_addresses: list of address_t;
!out_of_range: list of uint;
Specman e Language Reference
1999-2015

212

Product Version 15.1


All Rights Reserved.

store_address(v: uint) is {
if v in set_of_values(address_t) {
pending_addresses.add(v);
}
else if v in full_set_of_values(address_t) {
bad_addresses.add(v);
}
else {
out_of_range.add(v);
};
};

Specman e Language Reference


1999-2015

213
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

214

Product Version 15.1


All Rights Reserved.

Structs, Fields, and Subtypes

This chapter contains the following sections:

Structs Overview on page 216

Defining Structs on page 216

Extending Structs on page 219

Extending Subtypes on page 222

Defining Fields on page 225

Defining List Fields on page 231

Creating Subtypes with When on page 241

Extending When Subtypes on page 244

Defining Attributes on page 248

Comparison of When and Like Inheritance on page 252

See Also

Unit-Related Predefined Methods for Any Struct on page 307

Predefined Methods of Any Struct or Unit on page 1176

Syntactic Elements on page 42

Struct Hierarchy and Name Resolution on page 54

e Data Types on page 137

Defining and Extending Scalar Types on page 182

Chapter 11 Generation Constraints

Chapter 7 Methods

Chapter 25 List Pseudo-Methods

Specman e Language Reference


1999-2015

215
.

Product Version 15.1


All Rights Reserved.

Chapter 12 Events

Chapter 14 Temporal Struct and Unit Members

Chapter 16 Coverage Constructs

3.1

Structs Overview

Structs are used to define data elements and behavior of components of a test environment. A struct can
hold all types of data and methods.
All user-defined structs inherit from the Specman predefined base struct type, any_struct.
For reusability of e code, you can add struct members or change the behavior of a previously defined
struct with extend.
Inheritance is implemented in e by either of two of aspects of a struct definition:

when inheritance is specified by defining subtypes with when struct members

like inheritance is specified with the like clause in new struct definitions

The best inheritance methodology for most applications is when inheritance.

3.2

Defining Structs

3.2.1

struct

Purpose
Define a data struct

Category
Statement

Syntax
struct struct-type [like base-struct-type] {
[struct-member; ...]}
Syntax Example
type packet_kind: [atm, eth];
struct packet {
Specman e Language Reference
1999-2015

216

Product Version 15.1


All Rights Reserved.

len: int;
keep len < 256;
kind: packet_kind;
};

Parameters
struct-type

The name of the new struct type.

base-struct-type

The type of the struct from which the new struct inherits its members.

struct-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 definition of a struct can be empty, containing no members.

Description
Structs are used to define the data elements and behavior of components and the test environment.
Structs contain struct members of the types listed in the Parameters table. Struct members can be
conditionally defined (see Creating Subtypes with When on page 241).
The optional like clause is an inheritance directive. All struct members defined in base-struct-type are
implicitly defined in the new struct subtype, struct-type. New struct members can also be added to the
inheriting struct subtype, and methods of the base struct type can be extended in the inheriting struct
subtype.

Example 1
A struct type named transaction is defined in this example.
struct transaction {
address: uint;
data: list of uint;
transform(multiple:uint) is empty;
};

The transaction struct contains three members:


Specman e Language Reference
1999-2015

217
.

Product Version 15.1


All Rights Reserved.

address field

data field

transform() empty method definition

Example 2
In this example, a pci_transaction struct is derived from the transaction struct in the previous
example, using like inheritance. The following struct members are added in this inherited struct:

Fields named command, dual_address, and bus_id


(a type statement is included, to enumerate values for the command field)

A keep constraint

A when conditional subtype

An event definition

An on member

A cover group definition

The transform() method, defined as empty in the transaction base type, is given a method body
using the is only method extension syntax.
type PCICommandType: [ IO_READ=0x2, IO_WRITE=0x3,
MEM_READ=0x6, MEM_WRITE=0x7 ];
struct pci_transaction like transaction {
command : PCICommandType;
keep soft data.size() in [0..7];
dual_address: bool;
when dual_address {
address2: uint;
};
bus_id: uint;
event initiate;
on initiate {
out("An event has been initiated on bus ", bus_id);
};
cover initiate is {
item command;
};
transform(multiple:uint) is only {
address = address * multiple;
};
};

Specman e Language Reference


1999-2015

218

Product Version 15.1


All Rights Reserved.

Example 3
Additional subtypes can, in turn, be derived from a subtype. In the following example, an
agp_transaction subtype is derived from the pci_transaction subtype of the previous example. Each
subtype can add fields to its base type, and place its own constraints on fields of its base type.
type AGPModeType: [AGP_2X, AGP_4X];
struct agp_transaction like pci_transaction {
block_size: uint;
mode: AGPModeType;
when AGP_2X {
keep block_size == 32;
};
when AGP_4X {
keep block_size == 64;
};
};

See Also

Struct Members on page 45

Extending Structs on page 219

Extending Subtypes on page 222

Creating Subtypes with When on page 241

Comparison of When and Like Inheritance on page 252

Chapter 2 Data Types

Chapter 7 Methods

Chapter 11 Generation Constraints

Chapter 12 Events

Chapter 14 Temporal Struct and Unit Members

Chapter 16 Coverage Constructs

3.3
3.3.1

Extending Structs
extend type

Purpose
Extend an existing data struct
Specman e Language Reference
1999-2015

219
.

Product Version 15.1


All Rights Reserved.

Category
Statement

Syntax
extend [struct-subtype] base-struct-type {
[struct-member; ...]}
Syntax Example
type packet_kind: [atm, eth];
struct packet {
len: int;
kind: packet_kind;
};
extend packet {
keep len < 256;
};

Parameters
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. A struct member is one of the following types:

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.

Description
Adds struct members to a previously defined struct or struct subtype.

Specman e Language Reference


1999-2015

220

Product Version 15.1


All Rights Reserved.

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.

Notes
If like inheritance has been used on a struct type, there are limitations on how the original base struct
type definition can be further extended with extend. See Restrictions on Like Inheritance on page 261.

Example 1
In the following example, a struct type named pci_transaction is defined in one module, which is then
imported into another module where a field named data_phases and two constraints are added in an
extension to the struct.
<'
// module pci_transaction_definition.e
type PCICommandType: [ IO_READ=0x2, IO_WRITE=0x3,
MEM_READ=0x6, MEM_WRITE=0x7 ];
struct pci_transaction {
address: uint;
data: list of uint;
command : PCICommandType;
bus_id: uint;
event initiate;
on initiate {
out("An event has been initiated on bus ", bus_id);
};
cover initiate is {
item command;
};
};
'>
<'
// module pci_transaction_extension.e
import pci_transaction_definition;
extend pci_transaction {
data_phases: uint;
keep data_phases in [0..7];
keep data.size() == data_phases;
};
'>

Specman e Language Reference


1999-2015

221
.

Product Version 15.1


All Rights Reserved.

Example 2
In the following, the tx_packet struct inherits its kind field from the packet struct definition, from
which it is derived using like inheritance. The keep kind == atm constraint in the packet struct
extension applies to both packet instances and tx_packet instances. The keep len > 10 constraint in the
tx_packet subtype applies only to tx_packet instances, reducing the range of len in tx_packet instances
to [11..40]:
type packet_kind: [atm, eth];
struct packet {
len: int;
keep soft len <= 40;
kind: packet_kind;
};
struct tx_packet like packet {
send_delay: int [0..100];
keep len > 10;
};
extend packet {
keep kind == atm;
};

See Also

Defining Structs on page 216

Extending Subtypes on page 222

Creating Subtypes with When on page 241

Comparison of When and Like Inheritance on page 252

Chapter 2 Data Types

Chapter 7 Methods

Chapter 11 Generation Constraints

Chapter 12 Events

Chapter 14 Temporal Struct and Unit Members

Chapter 16 Coverage Constructs

3.4

Extending Subtypes

A struct subtype is an instance of the struct in which one of its fields has a particular value. For example,
the packet struct defined in the following example has atm packet and eth packet subtypes,
depending on whether the kind field is atm or eth.
type packet_kind: [atm, eth];
Specman e Language Reference
1999-2015

222

Product Version 15.1


All Rights Reserved.

struct packet {
len: int;
kind: packet_kind;
};

A struct subtype can optionally be specified with extend, so that the extension only applies to that
subtype.
Note Do not modify an object's determinant field in the context of an expression in which it has
already been determined. This behavior is under deprecation with the deprecation ID
DEPR_MODIFY_DETERMINANT_FIELD. The following code illustrates this issue:
type type_t: [GOOD, BAD];
struct A {
t: type_t;
};
extend GOOD A {
...
};
extend BAD A {
...
};
extend sys {
run() is also {
var a: GOOD A;
gen a;
a.t = BAD; \\ This behavior is deprecated because
\\ a is already determined as a GOOD A.
...

Example 1
The following shows a definition of a struct type named packet, an extension that adds a field named
len to the struct definition, and a second extension that adds a field named transmit_size only to
packets whose kind is transmit.
type packet_kind: [transmit, receive];
struct packet {
kind: packet_kind;
};
extend packet {
len: int;
Specman e Language Reference
1999-2015

223
.

Product Version 15.1


All Rights Reserved.

};
extend transmit packet {
transmit_size: int;
};

The extend transmit packet syntax above is equivalent to:


extend packet {
when transmit {
transmit_size: int;
};
};

Example 2
The packet struct definition below is extended with a Boolean field named legal. Two additional
extensions add a field named header to the packet struct: for packets whose legal value is TRUE, the
header field gets a legal_header struct instance. For packets whose legal values is FALSE, the
header field gets a bad_header struct instance.
type packet_kind: [atm, eth];
struct packet {
len: int;
keep soft len == 40;
kind: packet_kind;
};
extend packet{
legal: bool;
};
struct legal_header {
legal_ck: byte;
};
struct bad_header {
bad_ck: byte;
};
extend legal packet {
header: legal_header;
};
extend FALSE'legal packet {
header: bad_header;
};

Specman e Language Reference


1999-2015

224

Product Version 15.1


All Rights Reserved.

See Also

Defining Structs on page 216

Extending Structs on page 219

Creating Subtypes with When on page 241

Extending When Subtypes on page 244

3.5

Defining Fields

This section contains the following:

field on page 225

Constant Fields on page 228

3.5.1

field

Purpose
Define a struct field

Category
Struct member

Syntax
[const] [!][%] field-name[: type] [[min-val .. max-val]] [((bits | bytes):num)]
Syntax Example
type NetworkType: [IP=0x0800, ARP=0x8060] (bits: 16);
struct header {
address: uint (bits: 48);
hdr_type: NetworkType;
!counter: int;
};

Parameters
const

Denotes a field that contains a constant value throughout its lifetime. See
Constant Fields on page 228.

Specman e Language Reference


1999-2015

225
.

Product Version 15.1


All Rights Reserved.

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:
Note

You cannot declare the field as const if it is of list type.

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. If no range is specified, the range is the default range
for the fields type.
Note

(bits | bytes: num)

This syntax does not apply for const fields.

The width of a scalar 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.
Note This syntax is required for a physical field whose type does not have a
known width.

Description
Defines a field to hold data of a specific type. You can specify whether the field is:

A virtual field (the default) or a physical field (using %)

Automatically generated (the default) or ungenerated (using !)

Constant in its value throughout its lifetime (using const)

Accessible to code outside the structs package or family scope (using private | protected | package)

For scalar data types, you can also specify the size of the field in bits or bytes.
Unless you define a field as ungenerated, Specman generates a value for it when the struct is generated,
subject to any constraints that exist for the field. However, for all fields except those declared const, you
can 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 the ! option or the generation
constraints.

Specman e Language Reference


1999-2015

226

Product Version 15.1


All Rights Reserved.

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.

List Fields
See Defining List Fields on page 231 for the full syntax for defining list fields and a complete
description of their usage.

Physical Fields and Virtual 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, 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 fields type. For a physical field, if the
fields 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.

Example
The struct definitions below contain several types of fields.
type NetworkType: [IP=0x0800, ARP=0x8060] (bits: 16);
struct header {
%address: uint (bits: 48);
%length: uint [0 .. 32];
};
struct packet {
hdr_type: NetworkType;
%hdr: header;
is_legal: bool;
!counter: uint;
};

Specman e Language Reference


1999-2015

227
.

Product Version 15.1


All Rights Reserved.

extend sys {
packet;
};

The header struct contains two physical fields:

A field named address which is a 48-bit field of data type uint

A field named length of data type uint

The packet struct contains:

An enumerated hdr_type field that can be either IP or ARP

A physical field named hdr of type header, which will hold an instance of the header struct

A Boolean is_legal field

An ungenerated uint field named counter

The sys struct extension contains a field for an instance of a packet struct. No type declaration is
required for the packet field in the sys extension, since the field name is the same as the name of a type
that was already defined.

See Also

Constant Fields on page 228

Chapter 2 Data Types

Chapter 11 Generation Constraints

Chapter 20 Packing and Unpacking

list of on page 231

3.5.2

Constant Fields

A field declared const is assigned a value once during its initialization. Its value is kept constant from
then onward. The const keyword enforces the constant value.
The e compiler takes advantage of const declarations to optimize memory performance. You can expect
significant memory performance improvement if a field that serves as a when determinant is declared as
const. (For more information about when subtypes, see Creating Subtypes with When on page 241.)

Example
The following example illustrates basic methodology for using fields declared as const.
type packet_kind
struct packet {
Specman e Language Reference
1999-2015

: [SPLIT, TOKEN, SOF, DATA, HANDSHAKE, PREAMBLE];

228

Product Version 15.1


All Rights Reserved.

const %kind : packet_kind;


%data : list of int;
};
extend driver {
!pkt : packet;
send_packets() {
// pkt = new;
// pkt.kind = SOF;
// Illegal - will cause compile time error
pkt = new packet with {
.kind = SOF;
};
send( pkt );
for i from 0 to 10 {
gen pkt keeping {
.kind in [TOKEN,DATA,HANDSHAKE]; // ***
};
send( pkt );
};
};
rcv_packet(lob : list of byte)@packet_received {
var rcvd_pkt : packet;
unpack(packing.low,lob,rcvd_pkt);
};
};
extend packet {
post_generate() {
if should_be_token() {
kind = TOKEN;
// Illegal - will cause run time error
// because generation in line marked
// by *** assigned the value;
};
};
};

In This Section
The rest of this section describes:

Initializing const Fields for Structs on page 230

Initializing const Unit Fields on page 230

Notes about Initialization of const Fields on page 231

Specman e Language Reference


1999-2015

229
.

Product Version 15.1


All Rights Reserved.

Restrictions for const Fields on page 231

See Also

Tip: Use the const Field Modifier in the Specman Performance Handbook

3.5.2.1

Initializing const Fields for Structs

Initialization of const fields must be completed during the creation phase of a struct. Unless marked as
do-not-generate, the value of a const field is determined automatically at generation time (just like
non-constant fields).
If the const field is not generated, it can be assigned a value procedurally:

During generation, with pre_generate() or post_generate()

With an assignment action while creating an object, with a new...with action block or the init() method

In these contexts, a const field of the newly created struct may be used on the left side of an assignment
operator.
A const field is automatically initialized by built-in mechanisms such as unpack() (if the field is
physical), copy(), and read_binary_struct(). If the const field is virtual (not physical), it can be
assigned a value inside the scope of the do_unpack() hook method.

3.5.2.2

Initializing const Unit Fields

Units are only generated at pre-run time. In addition, the complete unit tree is generated before the
pre-run phase when connect_ports() and connect_pointers() are called. Therefore Specman allows
const fields of units to be initialized during connect_ports() and connect_pointers().

Examples
unit collector_u {
const !p_mon: monitor_u;
connect_pointers() is also {
p_mon = get_enclosing_unit(monitor_u);
};
};

unit collector_u {
const my_field: byte;
connect_pointers() is also {
my_field = 25;
Specman e Language Reference
1999-2015

230

Product Version 15.1


All Rights Reserved.

};
};

3.5.2.3

Notes about Initialization of const Fields

A compile-time error occurs if a const field is assigned a value from a scope other than those described
in Initializing const Fields for Structs and Initializing const Unit Fields.
Fields of enum types that are declared const have no default value upon creation of the struct (even
if zero is a possible enumerated value). They must be initialized as described in the sections above.

3.5.2.4

Restrictions for const Fields

Fields of list type cannot be declared const.

Fields declared under when subtypes with a non-constant determinant cannot be declared const.

A const field can be assigned a value only once. A run-time error occurs if a const field is assigned
more than one value.
Constant fields cannot be passed by reference.

3.6

Defining List Fields

This section shows the syntax and examples of lists in general, and of keyed lists. It contains these
topics:

list of on page 231

list(key) of on page 235

3.6.1

list of

Purpose
Define a list field

Category
Struct member

Specman e Language Reference


1999-2015

231
.

Product Version 15.1


All Rights Reserved.

Syntax
One-dimensional lists:
[!][%]list-name[[length-exp]]: list of type
Multi-dimensional lists:
[!][%]list-name[[length-exp]...]: list of... type
Syntax Examples
packets: list of packet;
matrix: list of list of int;
matrix_3d[5][5][5]: list of list of list of int;

Parameters
!

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

The name of the list being defined.

length-exp

An expression that gives the initial size for the list. The expression must evaluate to a
non-negative integer.
For multi-dimensional lists, you can enter sizes for sublists also. The number of length
expressions must be equal to or less than the number of list dimensions. For example:
f[3]: list of int; -- O.K.
f[3]: list of list of int; -- O.K.
f[3][2]: list of list of int; -- O.K.
f[3][2][5]: list of list of int; -- Error

type

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

Description
Defines a list of items of a specified type.
An initial size can be specified for the list. The list initially contains that number of items or, in the case
of multi-dimensional lists, sub-lists. 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. Note that, for multi-dimensional lists,
you can also specify the size of the sublists.

Specman e Language Reference


1999-2015

232

Product Version 15.1


All Rights Reserved.

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.
For information about initializing list items to particular values, see Assignment of Lists on page 175
and Constraining Lists in the Specman Generation User Guide.

Restrictions on Multi-Dimensional Lists

A multi-dimensional list cannot be used as the element type for simple, event, or buffer e ports.
Lists of lists of these ports are allowed, but not ports of lists of lists

Multi-dimensional lists are not supported for use with:

The Specman SystemVerilog adapter

External TLM ports

Code generation utilities (MLtypemap or SC2e)

The Pgen generator

Multi-dimensional lists are allowed as parameters for e2e and SystemC method ports.

Example 1
Three list fields are defined in the struct definitions below. The cell struct contains a list of bytes, the
packet struct contains a list of cell struct instances, and the sys struct extension contains a list of 16
packet struct instances.
struct cell {
%data: list of byte;
%length: uint;
};
struct packet {
%is_legal: bool;
cells: list of cell;
};
extend sys {
packets[16]: list of packet;
};

Example 2
The following example defines two multidimensional lists:

The list f1 (list of list of int) contains three list-of-int items, and each of those items consists of two
elements (two integers).

Specman e Language Reference


1999-2015

233
.

Product Version 15.1


All Rights Reserved.

The list f2 (list of list of list of int) contains ten list-of-list-of-int items, and each of those items consists
of five lists-of-int items. In addition, the list-of-int items contained in f2 are empty because they are
not generated.
extend sys {
f1[3][2]: list of list of int;
!f2[10][5]: list of list of list of int;
run() is also {
assert f1.size() == 3;
for each in f1 {
assert it.size() == 2;
};
assert f2.size() == 10;
for each in f2 {
assert it.size() == 5;
assert it.flatten().is_empty();
};
};
};

Example 3
Two lists of cells are defined in this following example, both with initial sizes specified using the
[length] syntax. For the cells_1 list, the length expression is a value generated from within the 16 to 32
range specified for the num_cells field. For the cells_2 list, the length expression is the integer value of
an item from the enumerated list named l_sel (sm has value 0, med has value 1, lge has value 3 due to
their positions in the enumerated list).
struct cell {
%data: list of byte;
%length: uint;
};
struct packet {
%is_legal: bool;
num_cells: int;
keep num_cells in [16..32];
cells_1[num_cells]: list of cell;
l_sel: [sm, med, lge];
cells_2[l_sel.as_a(int)]: list of cell;
};

Specman e Language Reference


1999-2015

234

Product Version 15.1


All Rights Reserved.

See Also

field on page 225

Expressions on page 52

Chapter 2 Data Types

Chapter 11 Generation Constraints

Chapter 20 Packing and Unpacking

Chapter 25 List Pseudo-Methods

Constraining Lists in Specman Generation User Guide

Using Bidirectional Generative List Pseudo-Methods in Specman Generation User Guide

3.6.2

list(key) of

Purpose
Define a keyed list field

Category
Struct member

Syntax
[!][%]list-name: [list of...] list(key: key-field) of type
Syntax Example
!locations: list(key: address) of location;

Parameters
!

Keeps the list from being generated. Keyed lists cannot be generated; therefore, the ! is
required for lists that are under generation. If the list is instantiated in a struct that is not
generated, the ! is not needed.

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

list-name

The name of the list being defined.

[list of...]

You can define multi-dimensional lists as keyed lists.

Specman e Language Reference


1999-2015

235
.

Product Version 15.1


All Rights Reserved.

key-field

The key of the list. For a list of structs, it is the name of a field of the struct. For a list of
scalar or string items, it is the item itself, represented by the it variable.
This is the field or value which the keyed list pseudo-methods will check when they operate
on the list.
Note

type

The key-field cannot itself be a list.

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

Description
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:

As a hash table, in which searching only for a key avoids the overhead of reading the entire contents
of each item in the list.
For a list that has the capacity to hold many items, but which in fact contains only a small percentage
of its capacity, randomly spread across the range of possible items. An example is a sparse memory
implementation.

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.

How the Syntax for Keyed Lists Differs from the Syntax for Regular Lists
Besides the key parameter, the keyed list syntax differs from regular list syntax in the following ways:

A keyed list cannot be generated. This means that:

You must build a keyed list item by item because you cannot generate it.
You must either define a keyed list with a ! or instantiate the list only in structs that are not
generated.

The [exp] list size initialization syntax is not allowed for keyed lists. That is, list[exp]: list(key:
key) of type is not legal. Similarly, you cannot use a keep constraint to constrain the size of a keyed
list.

Restrictions on Keyed Lists

You cannot update (modify) the value of the key itself. If you do so, the update will be ignored.

Specman e Language Reference


1999-2015

236

Product Version 15.1


All Rights Reserved.

(This limitation is related to the previous one.) If the key for a list of struct is a particular field, each
struct in the list is associated with the value of the field at the moment that the struct is added to the
list. The struct remains associated with that initial field value even if the field value changes at a later
time.
Keyed lists and regular (unkeyed) lists are different types. Assignment is not allowed between a
keyed list and a regular list. If list_a is a keyed list and list_b is a regular list, list_a = list_b is a syntax
error.

The key for a keyed list cannot be of type real.

The key for a keyed list cannot itself be a list of any kind.

The key for a keyed list cannot be of type set.

Some operations are less efficient for keyed lists than for unkeyed lists, because after they change
the list they must also update the keys. The following operations are not recommended on keyed lists:

slice assignment

list.reverse()

If the same key value exists in more than one item in a keyed list, the behavior of the keyed list
pseudo-methods is undefined.
The list.resize() pseudo-method cannot be used on keyed lists.

See Also

Keyed Lists on page 157

Keyed List Pseudo-Methods on page 1423

Example 1
In the following example, 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.
In the if action, the list.key_exists() and list.key_index() keyed list pseudo-methods are used to check
for the existence of an item with the value of 8, and to print the list and the key values index if it exists.
<'
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);
};
Specman e Language Reference
1999-2015

237
.

Product Version 15.1


All Rights Reserved.

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

Results
cl =

(10 items, dec):


13

11

14

.0

cl.key_index(8) = 2

Example 2
In the following example, the struct type named s has fields a and b. A keyed list of s structs, with the n
field as the key, is declared in the sys extension, and the list is built by the bl() method.
In the run() method, the list.key_exists() keyed list pseudo-method is used to check whether the value
98 occurs in the n field in any of the structs in the keyed list. It so happens that the n value in the fourth
struct in the list (index 3) is 98. Other keyed list pseudo-methods are then used to print the struct instance
and the list index number of the struct that has n equal to 98.
Note that two list instances, index 12 and index 15, have the value 95 for n. If 95 was entered as the key
value for the list.key_exists() and list.key_index() pseudo-methods, those methods would use the last
instance, that is index number 15, and ignore the instance with index 12.
<'
struct s {
n: byte;
b: bit;
};
extend sys {
!sl: list(key: n) of s;
bl() is {
for i from 0 to 15 {
var t: s;
gen t;
sl.add(t);
};
};
run() is also {
bl();
Specman e Language Reference
1999-2015

238

Product Version 15.1


All Rights Reserved.

print sl;
var b: bool;
b = sl.key_exists(98);
print b;
if b {
print sl.key(98);
print sl.key_index(98);
};
};
};
'>

Results
sl =
item

type

0.
s
109
1.
s
122
2.
s
133
3.
s
98
4.
s
163
5.
s
196
6.
s
159
7.
s
223
8.
s
118
9.
s
192
10.
s
22
11.
s
170
12.
s
95
13.
s
153
14.
s
169
15.
s
95
b = TRUE
sl.key(98) = s-@0: s

b
0
0
1
0
0
0
0
1
1
1
1
1
0
1
0
0

@tmp
0
1

n:
b:
sl.key_index(98) = 3

98
0

Example 3
In the following example, a keyed list is used to model sparse memory. A struct type named location has
address and value fields. A keyed list named locations, with address as the key, is used to hold instances
of location structs generated in the while loop. For each new location struct generated, the

Specman e Language Reference


1999-2015

239
.

Product Version 15.1


All Rights Reserved.

list.key_exists() pseudo-method checks to see if the list already contains an instance with that address
value. If it is not already in the list, the new instance is added to the list.This ensures that the keyed list
will contain exactly LLEN (50) items, all with different address values.
<'
define LLEN 50;
struct location {
address: uint(bits: 8);
value: int;
};
extend sys {
!locations: list(key: address) of location;
post_generate() is also {
var loc: location = new;
while locations.size() < LLEN do {
gen loc;
if locations.key_exists(loc.address) == FALSE then {
locations.add(loc);
};
};
};
};
'>

Example 4
This example includes a keyed list instantiated in a struct that is not generated. Thus, the ! is not required
in the keyed list syntax.
struct barca {
scorers:list (key:it) of string;
};
extend sys {
run() is also {
var b:barca = new;
b.scorers.add({"xavi";"pedro";"villa";"jeffren"});
print b.scorers.key_exists("messi");
};
};

Specman e Language Reference


1999-2015

240

Product Version 15.1


All Rights Reserved.

3.7

Creating Subtypes with When

The when struct member creates a conditional subtype of the current struct type, if a particular field of
the struct has a given value. This is called when inheritance, and is one of two techniques Specman
provides for implementing inheritance. The other is called like inheritance. When inheritance is
described in this section. Like inheritance is described in struct on page 216.
When inheritance is the recommended technique for modeling in Specman. Like inheritance is more
appropriate for procedural testbench programming. When and like inheritance are compared in
Comparison of When and Like Inheritance on page 252.

3.7.1

when

Purpose
Create a subtype

Category
Struct member

Syntax
when struct-subtype [base-struct-type]
{struct-member; ...}
Syntax Example
struct packet {
len: uint;
good: bool;
when FALSE'good {
pkt_msg() is {
out("bad packet");
};
};
};

Specman e Language Reference


1999-2015

241
.

Product Version 15.1


All Rights Reserved.

Parameters
struct-subtype

A subtype declaration in the form type-qualifier'field-name.


The type-qualifier is one of the legal values for the field named by field-name. If
the field-name is a Boolean field, and its value is TRUE for the subtype, you can
omit type-qualifier. That is, if big is a Boolean field, big is the same as
TRUE'big.
The field-name is the name of a field in the base struct type. Only Boolean or
enumerated fields can be used. If the field type is Boolean, the type qualifier must
be TRUE or FALSE. If the field type is enumerated, the qualifier must be a value
of the enumerated type. If the type qualifier can apply to only one field in the
struct, you can omit 'field-name.
More than one type-qualifier'field-name combination can be stated, to create a
subtype based on more than one field of the base struct type.

base-struct-type

(Optional) The struct type of the current struct (in which the subtype is being
created).

struct-member

Definition of a struct member for the struct subtype. One or more new struct
members can be defined for the subtype.

Description
You can use the when construct to create families of objects, in which multiple subtypes are derived
from a common base struct type.
A subtype is a struct type in which specific fields of the base struct have particular values. For example:

If a struct type named packet has a field named kind that can have a value of eth or atm,
then two subtypes of packet are eth packet and atm packet.
If the packet struct has a Boolean field named good, two subtypes are FALSEgood packet
and TRUEgood packet.

The field whose value determines the actual subtype of an object is called the determinant field.
Subtypes can be defined for combinations of values (of different determinant fields), such as good eth
packet.
Struct members you define in a when construct can be accessed only in the subtype, not in the base
struct. This provides a way to define a subtype that has some struct members in common with the base
type and all of its other subtypes, but has other struct members that belong only to the current subtype.

Specman e Language Reference


1999-2015

242

Product Version 15.1


All Rights Reserved.

Notes

Declaring the determinant field as const is recommended whenever the subtype of an object is not
intended to change during the course of its life (see field on page 225). This is especially true for
fields with many when variants, as it yields significant performance improvements. See also Tip:
Use the const Field Modifier in the Specman Performance Handbook.
Once you have used like inheritance to create a subtype of a base struct type, you cannot extend the
base type using when.
You can omit the base struct type name in the when construct because it is redundant.

Example 1
An instance of the packet struct below can have a kind of either transmit or receive. The when
construct creates a transmit packet subtype. The length field and the print() method apply only to
packet instances that have kind values of transmit.
type packet_kind: [transmit, receive];
struct packet {
const kind: packet_kind;
when transmit packet {
length: int;
print() is {
out("packet length is: ", length);
};
};
};

Example 2
The op1 field in the struct definition below can have one of the enumerated reg_n type values
(REG0, REG1, REG2, or REG3). The kind field can have a value of imm or reg, and the dest
field can have a value of mm_1 or reg.
The REG0'op1 subtype specification in the first when construct creates a subtype of instances in
which the op1 value is REG0. This subtype has all the instr struct fields plus a print_op1()
method.
The reg'kind subtype specification in the second when construct creates a subtype of instances in
which the kind value is reg. This subtype also has all the instr struct fields plus a print_kind()
method.
It is necessary to add the 'kind expression in the second when construct because the dest field can
also have a value of reg, which means that reg is ambiguous without the further specification of the
field name.

Specman e Language Reference


1999-2015

243
.

Product Version 15.1


All Rights Reserved.

type reg_n : [REG0, REG1, REG2, REG3];


struct instr {
%op1: reg_n;
kind: [imm, reg];
dest: [mm_1, reg];
};
extend instr {
when REG0'op1 {
print_op1() is {
out("instr op1 is REG0");
};
};
when reg'kind {
print_kind() is {
out("instr kind is reg");
};
};
};

See Also

Tip: Use the const Field Modifier in the Specman Performance Handbook

Defining Structs on page 216

Comparison of When and Like Inheritance on page 252

is [not] a on page 123

3.8

Extending When Subtypes

There are two general rules governing the extensions of when subtypes:

If a struct member is declared in the base struct, it cannot be re-declared in any when subtype, but it
can be extended.
With the exception of coverage groups and the events associated with them, any struct member
defined in a when subtype does not apply or is unknown in other subtypes, including:

fields
constraints
events
methods
on
expect
assume

Specman e Language Reference


1999-2015

244

Product Version 15.1


All Rights Reserved.

See Also

Coverage and When Subtypes on page 245

Extending Methods in When Subtypes on page 246

When Subtypes and expect on page 248

See Also

Defining Structs on page 216

Extending Structs on page 219

Extending Subtypes on page 222

Creating Subtypes with When on page 241

Rules for Extending Methods in Creating e Testbenches

3.8.1

Coverage and When Subtypes

All coverage events must be defined in the base struct. Defining the ready3 event within the ADD
subtype, for example, results in a load time error. Coverage groups can be defined in the base struct or in
the subtype.
struct operation {
opcode: [ADD, SUB];
op1: uint;
op2: uint;
op3: uint;
event ready is rise('top.ready');
event ready3 is rise('top.op3ready'); // Must define here
cover ready is {
item op1;
item op2;
cross op1, op2;
};
};
extend operation {
when ADD operation {
//
event ready3 is rise('top.op3ready'); // Can't define here
cover ready3 is {
item op1;
item op2;
item op3;
cross op1, op2, op3;
Specman e Language Reference
1999-2015

245
.

Product Version 15.1


All Rights Reserved.

};
};
};

3.8.2

Extending Methods in When Subtypes

A method defined or extended within a when construct is executed in the context of the subtype and can
freely access the unique struct members of the subtype with no need for any casting.
When a method is declared in a base type, each extension of the method in a subtype must have the same
parameters and return type as the original declaration. For example, because do_op() is defined with two
parameters in the base type, extending do_op() in the ADD subtype to have three parameters results in a
load time error.
struct operation {
opcode: [ADD, ADD3];
op1: uint;
op2: uint;
do_op(op1: uint, op2: uint): uint is {
return op1 + op2;
};
};
extend operation {
when ADD3 {
op3: uint;
//
do_op(op1:uint,op2:uint,op3:uint): uint is { // Load time error
//
return op1 + op2 +op3;
//
};
};
};

However, if a method is not declared in the base type, each definition of the method in a subtype can
have different parameters and return type. The following variation of the example above loads without
error.
struct operation {
opcode: [ADD, ADD3];
op1: uint;
op2: uint;
};
extend operation {
when ADD {
do_op(op1: uint, op2: uint): uint is {
Specman e Language Reference
1999-2015

246

Product Version 15.1


All Rights Reserved.

return op1 + op2;


};
};
when ADD3 {
op3: uint;
do_op(op1:uint,op2:uint,op3:uint): uint is {
return op1 + op2 +op3;
};
};
};

If more than one method of the same name is known in a when subtype, any reference to that method is
ambiguous and results in a load-time error. In the following example, the legal ethernet packet subtype
inherits two definitions of the method show(). The error is not reported when the ambiguity becomes
possible (when the legal ethernet packet subtype is extended) but when the reference to the show()
method is made.
type protocol: [ethernet, ieee, foreign];
struct packet {
legal: bool;
protocol;
when legal {
show() is {out("it is a legal packet")};
};
when ethernet {
show() is {out("it is a ethernet packet")};
};
when legal ethernet {
le:uint;
};
};
extend sys {
packets: list of packet;
post_generate() is {
//
for each legal ethernet packet (p) in packets {
//
p.show();
//
};
};
};

// Load-time error

To remove the ambiguity from such a reference, use the as_a() type casting operator or the when
subtype qualifier syntax:
p.as_a(legal packet).show();
Specman e Language Reference
1999-2015

247
.

Product Version 15.1


All Rights Reserved.

break on call legal packet.show()

Note Method calls are checked when the e code is parsed. If there is no ambiguity, the method to be
called is selected and all similar references are resolved in the same manner. In the example above, the
extension to ethernet packet could be placed in a separate file like this:
extend packet {
when ethernet {
show() is {out("it is a ethernet packet")};
};
};

If this file is loaded after the rest of the e code has been loaded, no error is issued because the method call
to p.show() was resolved when the first file was loaded. Any call to p.show() always prints:
it is a legal packet

3.8.3

When Subtypes and expect

The expect checker is launched at the start of the run phase, based on the when subtypes that were
selected during the generation phase. Even if you change the when determinant during the run, the
checker does not change.

3.9

Defining Attributes

You can define attributes that control how a field behaves when it is copied or compared. These
attributes are used by deep_copy(), deep_compare(), and deep_compare_physical().

3.9.1

attribute field

Purpose
Define the behavior of a field when copied or compared

Category
Struct member

Syntax
attribute field-name attribute-name = exp

Specman e Language Reference


1999-2015

248

Product Version 15.1


All Rights Reserved.

Syntax Example
attribute channel deep_copy = reference;

Parameters
field-name

The name of a field in the current struct.

attribute-name is one of the following:


deep_copy

Controls how the field is copied by the deep_copy() routine.

deep_compare

Controls how the field is compared by the deep_compare() routine.

deep_compare_physical

Controls how the field is compared by the deep_compare_physical()


routine.

deep_all

Controls how the field is copied by the deep_copy() routine or compared


by the deep_compare() or deep_compare_physical() routines.

exp is one of the following:


normal

Perform a deep (recursive) copy or comparison.

reference

Perform a shallow (non-recursive) copy or comparison.

ignore

Do not copy or compare.

Description
Defines how a field behaves when copied or compared. For a full description of the behavior specified
by each expression, see the description of the deep_copy() on page 1458, deep_compare() on page
1461, or deep_compare_physical() on page 1466 routine.
The attribute construct can appear anywhere, including inside a when construct or an extend construct.
To determine which attributes of a field are valid, Specman scans all extensions to a unit or a struct in the
order they were loaded. If several values are specified for the same attribute of the same field, the last
attribute specification loaded is the one that is used.

Example
This example shows the effects of field attributes on the deep_copy() and deep_compare() routines. An
instance of packet, which contains three fields of type port (also a struct type), is deep copied and
then deep compared. Because each of the three port fields has a different attribute, the way each field
is copied and compared is also different.

Specman e Language Reference


1999-2015

249
.

Product Version 15.1


All Rights Reserved.

<'
struct port {
%counter: int;
};
struct packet {
%parent: port;
attribute parent deep_all = reference;
%origin: port;
attribute origin deep_copy = ignore;
%dest: port;
attribute dest deep_copy = normal;
attribute dest deep_compare = ignore;
attribute dest deep_compare_physical = ignore;
%length: int;
};
extend sys {
run() is also {
var port1: port = new port;
var port2: port = new port;
var port3: port = new port;
var packet1: packet = new packet with {
.parent = port1;
.origin = port2;
.dest = port3;
};
var packet2: packet = deep_copy(packet1);
out("");
out("parent of packet1 is
: ", packet1.parent);
out("parent of packet1 should be: ",
port1, " original copy");
out("");
out("parent of packet2 is
: ", packet2.parent);
out("parent of packet2 should be: ", port1,
" shallow copy");
out("");
out("origin of packet1 is
: ", packet1.origin);
out("origin of packet1 should be: ", port2,

Specman e Language Reference


1999-2015

250

Product Version 15.1


All Rights Reserved.

" original copy");


out("");
out("origin of packet2 is
: ", packet2.origin);
out("origin of packet2 should be: \
a NULL port, attribute: copy: ignore");
out("");
out("dest of packet1 is
: ", packet1.dest);
out("dest of packet1 should be: ", port3);
out("");
out("dest of packet2 is
: ", packet2.dest);
out("dest of packet2 should be: a different \
port, attribute: copy: normal (deep)");
out("");
packet2.dest = new port; // force different field value
var ldiff: list of string =
deep_compare(packet1, packet2, UNDEF);
out(ldiff, "\n");
out("Notice a diff in the origin field, \
attribute is normal for deep_compare");
out("Notice no diff for the dest field, \
attribute is ignore for deep_compare");
out("");
};
};
'>

Results
Here are the results of running the packet example:
1
2
3
4
5
6
7
8
9
10
11

Specman > run


Running the test ...
parent of packet1 is
: port-@0
parent of packet1 should be: port-@0 original copy
parent of packet2 is
: port-@0
parent of packet2 should be: port-@0 shallow

copy

origin of packet1 is
: port-@1
origin of packet1 should be: port-@1 original copy

Specman e Language Reference


1999-2015

251
.

Product Version 15.1


All Rights Reserved.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

origin of packet2 is
: (a NULL port)
origin of packet2 should be: a NULL port,
attribute: copy: ignore
dest of packet1 is
: port-@2
dest of packet1 should be: port-@2
dest of packet2 is
: port-@3
dest of packet2 should be: a different port,
attribute: copy: normal (deep)
Differences between packet-@4 and packet-@5
-------------------------------------------------origin:
port-@1
!=
(a NULL port)
Notice a diff in the origin
attribute is normal for
Notice no diff for the dest
attribute is ignore for

field,
deep_compare
field,
deep_compare

Lines 4-8 Because the parent field has the deep_all attribute reference, the parent field of the packet2
instance contains a pointer to the parent field of packet1 (port-@0).
Lines 10-15 Because the origin field has the deep_copy attribute ignore, the origin field of the packet2

instance contains a NULL instance of type port.


Lines 17-22 Because the dest field has the deep_copy attribute normal, the dest field of the packet2

instance contains a new instance of type port (port-@3).


Lines 24-26 These lines show the results of a deep_compare() of packet1 and packet2. Note that just

prior to this comparison, a new instance of type port was assigned to the dest field of packet2. However,
no difference is reported for the dest fields of the two packet instances, because the deep_compare
attribute of the dest field is ignore. A difference is reported for the origin field because the
deep_compare attribute is normal and the fields are not the equal.

See Also

deep_copy() on page 1458

deep_compare() on page 1461

deep_compare_physical() on page 1466

3.10 Comparison of When and Like Inheritance


There are two ways to implement object-oriented inheritance in e:
Specman e Language Reference
1999-2015

252

Product Version 15.1


All Rights Reserved.

Like inheritance is the classical, single inheritance familiar to users of all object-oriented languages.
When inheritance is a concept introduced by e. It is less familiar initially, but lends itself more easily
to the kind of modeling that people do in e.

The following sections discuss the pros and cons of both these types of inheritance and recommends
when to use each of them:

Summary of When versus Like on page 253

A Simple Example of When Inheritance on page 253

A Simple Example of Like Inheritance on page 255

Advantages of Using When Inheritance for Modeling on page 256

Advantages of Using Like Inheritance on page 259

Restrictions on Like Inheritance on page 261

A When Inheritance Example on page 263

3.10.1

Summary of When versus Like

In general, when inheritance should be used for modeling all DUT-related data structures. It is
superior from a knowledge representation point of view and from an extensibility point of view. When
inheritance lets you:

Explicitly reference a field that determines the when subtype

Create multiple, orthogonal subtypes

Use random generation to generate lists of objects with varying subtypes

Easily extend the struct later

Although like inheritance has more restrictions than when inheritance, it is recommended in some
special cases because:

Like inheritance is somewhat more efficient than when inheritance.

Generation of objects that use like inheritance can also be more efficient.

3.10.2

A Simple Example of When Inheritance

You can create a when subtype of a generic struct using any field in the struct that is a Boolean or
enumerated type. This field, which determines the when subtype of a particular struct instance, is called
the when determinant. In the following example, the when determinant is legal.
struct packet {
legal: bool;

Specman e Language Reference


1999-2015

253
.

Product Version 15.1


All Rights Reserved.

when legal {
pkt_msg() is {
out("good packet");
};
};
};

Note

The following syntax is used in this document because it looks closer to the like version:

extend legal packet {...}

This syntax is exactly equivalent to the when construct:


extend packet {when legal {...}}

The following example shows a generic packet struct with 3 fields, protocol, size and data, and an
abstract method show(). In this example, the protocol field is the determinant of the when version of
the packet. That is, this field determines whether the packet instance has a subtype of IEEE,
Ethernet, or foreign. In this example. the Ethernet packet subtype is extended by adding a field and
extending the show() method.
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
show() is undefined; // To be defined by children
};
extend Ethernet packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};

Of course, it is possible for a struct to have more than one when determinant. In the following example,
the Ethernet packet subtype is extended with a field of a new enumerated type, Ethernet_op.
type Ethernet_op: [e1, e2, e3];
extend Ethernet packet { op: Ethernet_op; };
extend e1 Ethernet packet {
e1_foo: int;
show() is {out("I am an e1 Ethernet packet")};
};

Because it is possible for a struct to have more than one when determinant, the inheritance tree for a
struct using when inheritance consists of any number of orthogonal trees, each rooted at a separate
enumerated or Boolean field in the struct. Figure 3-1 shows a when inheritance tree consisting of 3
orthogonal trees rooted in the legal, protocol, and op fields. Note that the when subtypes that have not
been explicitly defined, such as IEEE packet, exist implicitly.

Specman e Language Reference


1999-2015

254

Product Version 15.1


All Rights Reserved.

Figure 3-1

When Inheritance Tree for Packet Struct Subtypes


packet

TRUE

legal
FALSE
protocol

IEEE

foreign

Ethernet
op

e1

3.10.3

e2

e3

A Simple Example of Like Inheritance

You can create a like child of a generic struct using the like construct. In this example, a child
Ethernet_packet is created from the generic struct packet and is extended by adding a field and
extending the show() method.
struct packet {
size: int [0..1k];
data[size]: list of byte;
show() is undefined; // To be defined by children
};
struct Ethernet_packet like packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};
...

In the same way, you can create an IEEE_packet from packet using like:
struct IEEE_packet like packet {
i_field: int;
show() is {out("I am an IEEE packet")};
};
Specman e Language Reference
1999-2015

255
.

Product Version 15.1


All Rights Reserved.

You can also easily create an e1_Ethernet_packet from Ethernet_packet using like inheritance.
struct e1_Ethernet_packet like Ethernet_packet {
e1_foo: int;
show() is {out("I am an e1 Ethernet packet")};
};

In contrast to the when inheritance tree, the like inheritance tree for the packet type is a single tree where
each subtype must be defined explicitly, as shown in Figure 3-2. This difference between the like and
when inheritance trees is the essential difference between like and when inheritance.
Figure 3-2

Like Inheritance Tree for Packet Struct Subtypes

packet

Ethernet_packet

IEEE_packet

e1_Ethernet_packet

3.10.4

Advantages of Using When Inheritance for Modeling

While the like version and the when version look similar, and the like version may seem more natural
to people familiar with other object-oriented languages, the when version is much better for the kind
of modeling people do in Specman. There are several reasons for this, which are explained in more
detail below:

You can refer explicitly to the determinant fields

You can create multiple orthogonal subtypes

You can use random generation to create lists of objects with varying subtypes

You can easily extend the struct later

You can create a new type by simple extension

You can refer explicitly to the determinant fields


In the when version, the determinant of the when is an explicit field. In the like version, there is no
explicit field that determines whether a packet instance is an Ethernet packet, an IEEE packet, or a
foreign packet. The explicit determinant fields provide several advantages:
Specman e Language Reference
1999-2015

256

Product Version 15.1


All Rights Reserved.

Explicit determinant fields are more intuitive.


Fields are more tangible than types and correspond better to the way hardware engineers perceive
architectures. Having a field whose value determines what fields exist under it is familiar to
engineers. (It is similar to C unions, for example.)

You can specify the attributes of determinants that are physical fields.
If the determinant is a physical field, you probably want to specify its size in bits, the mapping of
enumerated items to values, where it is in the order of fields, and so on. These things are done very
naturally with when inheritance, because the determinant is just another field. For example:
%protocol: packet_protocol (bits: 2);

With like inheritance, you can define the same field as the when determinant, but you also have to
tie it to the type with code equivalent to the following:
var pkt: packet;
case protocol {
Ethernet {var epkt: Ethernet packet; gen epkt; pkt = epkt;};
IEEE {var ipkt: IEEE packet; gen ipkt; pkt = ipkt;};
};

There is an added inconvenience of having to generate or calculate protocol separately from the rest
of the packet.

You can constrain the when determinant.


Using when inheritance, it is very natural to write constraints like these in a test:
keep
keep
keep
keep

protocol in [Ethernet, IEEE];


protocol != IEEE;
soft protocol == select { 20: IEEE; 80: foreign; };
packets.is_all_iterations(.protocol, ...);

Constraining the value of fields in various ways is a main feature of Specman generation. Doing the
same with like inheritance is more complicated. For example, the first constraint above might be
stated something like this:
keep me is an Ethernet_packet or me is an IEEE_packet;
// This pseudocode is not a legal constraint specification

However, constraints like this can become quite complex in like inheritance. Furthermore, there is
no way to write the last two constraints.

You can create multiple orthogonal subtypes


Suppose each packet (of any protocol) can be either a normal (data) packet, an ack packet or a nack
packet, except that foreign packets are always normal:
type packet_kind: [normal, ack, nack];
Specman e Language Reference
1999-2015

257
.

Product Version 15.1


All Rights Reserved.

extend packet {
kind: packet_kind;
keep protocol == foreign => kind == normal;
};
extend normal packet { n1: int; };
...

How do you do this in like inheritance? Disregard for now the issue of extending the packet struct later.
Assume that you know the requirement stated above in advance, and you want to model it using like
inheritance in the best possible way.
Here is one way:
struct normal_Ethernet_packet like Ethernet_packet {
n1: int;
};
struct ack_Ethernet_packet like Ethernet_packet { ... };
struct nack_Ethernet_packet like Ethernet_packet { ... };
struct normal_IEEE_packet like IEEE_packet { ... };
// ...

This requires eight declarations.


Then, the Ethernet_op possibilities must be taken into account:
struct ack_e1_Ethernet_packet like e1_Ethernet_packet { ... }
// ...

This works, but requires ((N1 * N2 * ... * Nd) - IMP) declarations, where d is the number of orthogonal
dimensions, Ni is the number of possibilities in dimension i, and IMP is the number of impossible cases.
Another issue is how to represent the impossible cases.
Multiple inheritance would solve some of these problems, but would introduce new complications.
With when inheritance all the possible combinations exist implicitly, but you do not have to enumerate
them all. It is only when you want to say something about a particular one that you mention it, as in the
following examples:
extend normal IEEE packet { ni_field: int; }; // Adds a field
extend ack e1 Ethernet packet { keep size == 0; };
// Adds a constraint

All in all, the when version is more natural from a knowledge representation point of view, because:

It is immediately clear from the description what goes with what

You only need to mention types if you have something to say about them

Specman e Language Reference


1999-2015

258

Product Version 15.1


All Rights Reserved.

You can use random generation to create lists of objects with varying subtypes
The job of the generator is to create (in this example) packet instances. By default, all possible packets
should be generated. In both versions, you would create a list of packets. For example:
extend sys { packets: list of packet; };

However, the generator should only generate fully instantiated packets. In the when version, that
happens automaticallythere is no other way.
With like inheritance, if you generate a parent struct, only that parent struct is created; none of the like
children are created. For example, the following gen action always creates a generic packet, never an
Ethernet packet or an IEEE packet:
pkt: packet;
gen pkt;

Thus, in practice you should only generate fields whose type is a leaf in the like inheritance tree. For
example, you normally write:
p: e1_Ethernet_packet;
gen p;

You can easily extend the struct later


There are some restrictions on extending structs that have like children. Details are in Restrictions on
Like Inheritance on page 261.

You can create a new type by simple extension


You can extend the packet_protocol type and add new members to the packet subtype, for example:
extend packet_protocol: [brand_new];
extend brand_new packet {
...new struct members...
};

Automatically your old environment is able to generate brand_new packets. With like inheritance, you
have to find all instances of the procedural generation code and add the new case to the case statement.

3.10.5

Advantages of Using Like Inheritance

Like inheritance is a shorthand notation for a subset of when inheritance. It is restricted but more
efficient.
Like inheritance often has better performance than when inheritance for the following reasons:

Specman e Language Reference


1999-2015

259
.

Product Version 15.1


All Rights Reserved.

Method calling is faster for like inheritance.


When generation is slower then like generation. This can be important if a large part of the total run
time is attributable to generation.
When inheritance uses more memory because all of the fields of all of the when subtypes consume
space all the time.
Note If this becomes a problem in a particular design, there is a workaround. Rather than having
many separate fields under the when, put all the fields into a separate struct and put a single field for
that struct under the when. For example, the following coding style may use a lot of memory if there
are many fields declared under the Ethernet packet subtype.
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
when Ethernet {
e_field0: int;
e_field1: int;
e_field2: int;
e_field3: int;
// ...
};
};

A more efficient coding style is shown below, where a single field is declared under the Ethernet
packet subtype.
type packet_protocol: [Ethernet, IEEE, foreign];
struct Ethernet_packet {
e_field0: int;
e_field1: int;
e_field2: int;
e_field3: int;
// ...
};
struct packet {
protocol: packet_protocol;
when Ethernet packet {
e_packet: Ethernet_packet;
};
};

When to Use Like Inheritance


Like inheritance should be used for modeling only when the performance win is big enough to offset the
restrictions, for example:

Specman e Language Reference


1999-2015

260

Product Version 15.1


All Rights Reserved.

Objects that use a lot of memory, such as a register file, where the number of distinct registers is very
large, and for each such register a field of the register type must be generated, for example,
pc: pc_reg, psr: psr_reg and so on.
Objects that do not require randomization, such as a scoreboard or a memory.

Like inheritance should also be used for non-modeling, programming-like activities, such as
implementing a generic package for a queue.

3.10.6

Restrictions on Like Inheritance

There are four types of restrictions on like inheritance:

Restrictions Due to Inherent Differences on page 261

Restrictions Due to Implementation on page 261

Examples of Like Inheritance Restrictions on page 262

3.10.6.1 Restrictions Due to Inherent Differences


Some of the restrictions on like inheritance derive from the inherent differences between when and like
inheritance:

You cannot explicitly reference the determinant fields.

Creating multiple, orthogonal subtypes can be difficult with like inheritance.

Generation of parent does not create like children.

You cannot add when subtypes to a struct with like children. Similarly, you cannot create a like child
from a struct that has when subtypes. See Example 1 on page 262 for more information.

For more information on the first 3 items in this list, see Advantages of Using When Inheritance for
Modeling on page 256.

3.10.6.2 Restrictions Due to Implementation


In addition, the following restrictions are implementation-based and may be removed in future releases:

You cannot extend a struct with like children by:

Extending or overriding a TCM, if the TCM has been modified by one of the like children.
Adding fields, unless none of the like children have added fields either explicitly or implicitly.
(Adding an event or a dynamic C routine might implicitly add a field, for example.)
Adding an event, unless none of the like children have added fields either explicitly or implicitly.

Specman e Language Reference


1999-2015

261
.

Product Version 15.1


All Rights Reserved.

Adding or modifying an expect or assume, unless none of the like children have added fields
either explicitly or implicitly.
Adding a dynamic C routine, unless none of the like children have added fields either explicitly
or implicitly.

You cannot modify in a like child a cover group whose event is defined in the parent.

For more information see See Examples of Like Inheritance Restrictions on page 262.

3.10.6.3 Examples of Like Inheritance Restrictions


Restrictions on like inheritance are demonstrated in the following sample e code.

Example 1
You cannot add when subtypes to a struct with like children. Similarly, you cannot create a like child
from a struct that has when subtypes.
type protocol: [Ethernet, IEEE, foreign];
struct packet {
p: protocol;
data:list of byte;
};
struct tx_packet like packet {
t:uint
};
extend packet {
// Load-time error
//
when Ethernet {
//
e:uint;
//
};
};

Example 2
You cannot extend or override a TCM in a struct that has like children, if the TCM has been modified by
one of the like children.
struct packet {
event clk is rise ('~/top.clk');
zip()@clk is {wait [4]};
};
struct tx_packet like packet {
t:uint;
Specman e Language Reference
1999-2015

262

Product Version 15.1


All Rights Reserved.

zip()@clk is also {wait [2]};


};
extend packet {
// Load-time error
//
zip()@clk is also {wait [5]};
};

Example 3
You cannot modify in a like child a cover group whose event is defined in the parent. It may load without
error, but it will fail in unpredictable ways when run.
struct packet {
len: uint;
addr:uint;
event clk is rise ('~/top.clk')@sim;
event packet_sent;
cover packet_sent is {
item len;
item addr;
};
};
struct tx_packet like packet {
t:uint;
// cover packet_sent is {
//
item len;
//
item addr;
//
item t;
// };
};

3.10.7

// Error

A When Inheritance Example

The following example contains the e code fragments in the section titled A Simple Example of When
Inheritance on page 253.
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
show() is undefined;
Specman e Language Reference
1999-2015

263
.

Product Version 15.1


All Rights Reserved.

};
extend Ethernet packet {
e_field: int;
show() is {out("I am an Ethernet packet")};
};
extend IEEE packet {
i_field: int;
show() is {out("I am an IEEE packet")};
};
extend foreign packet {
f_field: int;
show() is {out("I am a foreign packet")};
};
type Ethernet_op: [e1, e2, e3];
extend Ethernet packet { op: Ethernet_op; };
extend e1 Ethernet packet {
e1_foo: int;
show() is {out("I am an e1 Ethernet packet")};
};
extend e2 Ethernet packet {
e2_foo: int;
show() is {out("I am an e2 Ethernet packet")};
};
extend e3 Ethernet packet {
e3_foo: int;
show() is {out("I am an e3 Ethernet packet")};
};
extend sys {
packets: list of packet;
post_generate() is also { for each in packets {.show()}; };
};

Specman e Language Reference


1999-2015

264

Product Version 15.1


All Rights Reserved.

Units

This chapter describes the constructs used to define units and explains how you can use units to
implement a modular verification methodology. This chapter contains the following sections:

Units Overview on page 265

Defining Units and Fields of Type Unit on page 270

Predefined Attributes and Methods for Any Unit on page 282

Unit-Related Predefined Methods for Any Struct on page 307

Unit-Related Predefined Routines on page 317

See Also

Chapter 3 Structs, Fields, and Subtypes

4.1

Units Overview

Units are the basic structural blocks for creating verification modules (verification cores) that can easily
be integrated together to test larger and larger portions of an HDL design as it develops. Units, like
structs, are compound data types that contain data fields, procedural methods, and other members.
Unlike structs, however, a unit instance is bound to a particular component in the DUT (an HDL path).
Furthermore, each unit instance has a unique and constant place (an e path) in the runtime data structure
of an e program. Both the e path and the complete HDL path associated with a unit instance are
determined during pre-run generation.
The basic runtime data structure of an e program is a tree of unit instances whose root is sys, the only
predefined unit in Specman. Additionally there are structs that are dynamically bound to unit instances.
The runtime data structure of a typical e program is similar to that of the XYZ_router program shown in
Figure 4-1.

Specman e Language Reference


1999-2015

265
.

Product Version 15.1


All Rights Reserved.

Figure 4-1

Run-Time Data Structure of the XYZ_Router

key
unit instance

sys

struct instance
field

XYZ_router

chan0

chan1

chan2

kind

addr

len

current_packet

data

parity

Each unit instance in the unit instance tree of the XYZ_router matches a module instance in the Verilog
DUT, as shown in Figure 4-2. The one-to-one correspondence in this particular design between e unit
instances and DUT module instances is not required for all designs. In more complex designs, there may
be several levels of DUT hierarchy corresponding to a single level of hierarchy in the tree of e unit
instances.
Figure 4-2

DUT Router Hierarchy


top

router_i

chan0

chan1

chan2

Binding an e unit instance to a particular component in the DUT hierarchy allows you to reference
signals within that DUT component using relative HDL path names. When the units are integrated into
a unit instance tree during pre-run generation, Specman determines the complete path name for each
referenced HDL object by concatenating the complete HDL path of the parent unit to the path of the unit
containing the referenced object. Specman is thus able to check the validity of the HDL references
before starting a simulation run.

Specman e Language Reference


1999-2015

266

Product Version 15.1


All Rights Reserved.

This ability to use relative path names to reference HDL objects allows you to freely change the
combination of verification cores as the HDL design and the verification environment evolve.
Regardless of where the DUT component is instantiated in the final integration, the HDL path names in
the verification environment remain valid.

See Also

Units vs. Structs on page 267

HDL Paths and Units on page 268

Methodology Recommendations and Limitations on page 269

Simulator users: Verilog and VHDL Stubs Files and Units on page 833

Relative Paths, Absolute Paths, and Units in the Specman Integrators Guide

4.1.1

Units vs. Structs

The decision of whether to model a DUT component with a unit or a struct often depends on your
verification strategy. Compelling reasons for using a unit instead of a struct include:

You intend to test the DUT component both standalone and integrated into a larger system.
Modeling the DUT component with a unit instead of a struct allows you to use relative path names
when referencing HDL objects. When you integrate the component with the rest of the design, you
simply change the HDL path associated with the unit instance and all the HDL references it contains
are updated to reflect the components new position in the design hierarchy.
This methodology eliminates the need for computed HDL names (for example, (path_str).sig),
which impact runtime performance.

Your e program has methods that access many signals at runtime.


The correctness of all signal references within units are determined and checked during pre-run
generation.
If your e program does not contain user units, the absolute HDL references within structs are also
checked during pre-run generation. However, if your e program does contain user units, the relative
HDL references within structs are checked at run time. In this case, using units rather than structs
can enhance runtime performance.

On the other hand, using a struct to model abstract collections of data, like packets, allows you more
flexibility as to when you generate the data. With structs, you can generate the data either during pre-run
generation, at runtime, or on the fly, possibly in response to conditions in the DUT. Unit instances,
however, can only be generated during pre-run generation, because each unit instance has a unique and
constant place (an e path) in the runtime data structure of an e program, just as an HDL component
instance has a constant place in the DUT hierarchical tree.Thus you cannot modify the unit tree by
generating unit instances on the fly.
Specman e Language Reference
1999-2015

267
.

Product Version 15.1


All Rights Reserved.

Any allocated struct instance automatically establishes a reference to its parent unit. If this struct is a
generated during pre-run generation it inherits the parent unit of its parent struct. If the struct is
dynamically allocated by the new or gen action, then the parent unit is inherited from the struct
belonging to the enclosing method.

See Also

HDL Paths and Units on page 268

Simulator users: Verilog and VHDL Stubs Files and Units on page 833

Relative Paths, Absolute Paths, and Units in the Specman Integrators Guide

Methodology Recommendations and Limitations on page 269

4.1.2

HDL Paths and Units

Relative HDL paths are essential in creating a verification module that can be used to test a DUT
component either standalone or integrated into different or larger systems. Binding an e unit instance to
a particular component in the DUT hierarchy allows you to reference signals within that DUT
component using relative HDL path names. Regardless of where the DUT component is instantiated in
the final integration, the HDL path names are still valid. To illustrate this, lets look at how the
XYZ_router (shown in Figure 4-1 on page 266) is bound to the DUT router (shown in Figure 4-2 on
page 266).
To associate a unit or unit instance with a DUT component, you use the hdl_path() method within a
keep constraint. For example, the following code extends sys by creating an instance of the XYZ_router
unit and binds the unit instance to the router_i instance in the DUT.
extend sys {
unit_core: XYZ_router is instance;
keep unit_core.hdl_path() =="~/top.router_i";
};

Similarly, the following code creates three instances of XYZ_channel in XYZ_router and constrains the
HDL path of the instances to be chan0, chan1, chan2. These are the names of the channel
instances in the DUT relative to the router_i instance.
unit XYZ_router {
channels: list of XYZ_channel is instance;
keep channels.size() == 3;
keep for each in channels {.hdl_path() ==
append("chan", index); };
};

Specman e Language Reference


1999-2015

268

Product Version 15.1


All Rights Reserved.

Specman determines the full HDL path of each unit instance during pre-run generation, by appending
the HDL path of the child unit instance to the full path of its parent, starting with sys. sys has the empty
full path . Thus the full path for the XYZ_router instance is top.router_i and that for the first channel
instance is top.router_i.chan0.
By default, the do_print() method of any unit prints two predefined lines as well as the user-defined
fields. The predefined lines display the e path and the full HDL path for that unit. The e path line
contains a hyperlink to the parent unit.

See Also

Specman Canonical Naming Conventions in the Specman Integrators Guide

Relative Paths, Absolute Paths, and Units in the Specman Integrators Guide

4.1.3

Unit Hierarchical References

Within units you can create hierarchical references to units or structs nested in other units by creating a
field of the unit type. In most cases, you need to set a read_only() constraint to specify the architectural
dependencies between components.

See Also

Propagating Data when Generating the VE in the Specman Generation User Guide

4.1.4

Methodology Recommendations and Limitations

Each unit instance has a unique and constant place (an e path) in the runtime data structure of an e
program that is determined during pre-run generation. Therefore, you cannot modify the unit tree
created during pre-run generation by generating unit instances on the fly or making assignments of new
values to existing unit instances. You can generate fields of unit type dynamically. However, when you
generate a field of type unit, either on-the-fly or during pre-run generation, you must constrain the field
to refer to an existing unit instance.
The following limitations are implied by the nature of unit instances and fields of unit type:

Unit instances cannot be the object of a new or gen action or a call to copy().

Unit instances cannot be placed on the left-hand-side of the assignment operator.

List methods that alter the original list, like list.add() or list.pop() cannot be applied to lists of unit
instances.
Units are intended to be used as structural components and not as data carriers. Therefore, using
physical fields in unit instances, as well as packing or unpacking into unit instances is not
recommended. Unpacking into a field of type unit when the field is NULL causes a runtime error.

Specman e Language Reference


1999-2015

269
.

Product Version 15.1


All Rights Reserved.

All instances of the same unit type must be bound to the same kind of HDL component.

If you intend to create a modular verification environment, the following recommendations are also
important:

Avoid setting global configuration options with set_config(). Instead, for numeric settings, use
set_config_max().
Avoid global changes to the default packing options. Instead, define unit-specific options in the
top-level unit and access them from lower-level units with get_enclosing_unit().
References to HDL objects should be placed in unit methods. If you need to access HDL objects
from struct methods, you may declare additional methods in a unit. Because these access methods
will probably be one line of e code, you can declare them as final methods for maximum efficiency.
For example, to access the following method declared in a struct,
final get_reset_value():bit is { return 'reset'; };

you would use


get_enclosing_unit(CONTROLLER).get_reset_value();

In structs that may be dynamically associated with more than one unit, it is recommended to use
computed path names.
Pre-run generation is performed before creating the stubs file. To minimize the time required to create
a stubs file, you can move any pre-run generation that is not related to building the tree of unit
instances into the procedural code, preferably as an extension of the run() method of the appropriate
structs. For example, you probably want to avoid generating thousands of packets in order to create
a stubs file.

4.2

Defining Units and Fields of Type Unit

The following sections describe the constructs for defining units and fields of type unit:

unit on page 271

field: unit-type is instance on page 275

field: unit-type on page 277

field: list of unit instances on page 279

field: list of unit-type on page 280

Specman e Language Reference


1999-2015

270

Product Version 15.1


All Rights Reserved.

4.2.1

unit

Purpose
Define a data struct associated with an HDL component or block

Category
Statement

Syntax
unit unit-type [like base-unit-type] {
[unit-member; ...]}
Syntax Example
unit XYZ_channel {
event external_clock;
event packet_start is rise('valid_out')@sim;
event data_passed;
verilog variable 'valid_out' using wire;
data_checker() @external_clock is {
while 'valid_out' == 1 {
wait cycle;
assert 'data_out' == 'data_in';
};
emit data_passed;
};
on packet_start {
start data_checker();
};
};

Parameters
unit-type

The type of the new unit.

base-unit-type

The type of the unit from which the new unit inherits its members.

Specman e Language Reference


1999-2015

271
.

Product Version 15.1


All Rights Reserved.

unit-member; ... The contents of the unit. Like structs, units can have the following types of 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
Unlike structs, units can also have verilog members. This capability lets you create
Verilog stub files for modular designs. Third-party simulator users should see the
following for information on which verilog members are recommended: Verilog and
VHDL Stubs Files and Units on page 833.

The definition of a unit can be empty, containing no members.

Description
Units are the basic structural blocks for creating verification modules (verification cores) that can easily
be integrated together to test larger designs. Units are a special kind of struct, with two important
properties:

Units or unit instances can be bound to a particular component in the DUT (an HDL path).
Each unit instance has a unique and constant parent unit (an e path). Unit instances create a static
tree, determined during pre-run generation, in the runtime data structure of an e program.

Because the base unit type (any_unit) is derived from the base struct type (any_struct), user-defined
units have the same predefined methods. In addition, units can have verilog members and have several
specialized predefined methods.
A unit type can be extended or used as the basis for creating unit subtypes. Extended unit types or unit
subtypes inherit the base types members and contain additional members.
See Units vs. Structs on page 267 for a discussion of when to use units instead of structs.

Example
This example defines a unit type XYZ_router.
<'
unit XYZ_router {
debug_mode: bool;

Specman e Language Reference


1999-2015

272

Product Version 15.1


All Rights Reserved.

channels: list of XYZ_channel is instance;


keep channels.size() == 3;
keep for each in channels {
.hdl_path() == append("chan", index);
.router == me };
event pclk is rise('clock')@sim;
mutex_checker() @pclk is {
while ('packet_valid') {
var active_channel: int = UNDEF;
for each in channels {
if '(it).valid_out' {
check that active_channel == UNDEF else
dut_error ("Violation of the mutual \
exclusion by channels ",
active_channel, " and ", index);
active_channel = index;
check that active_channel == 'addr' else
dut_error ("Violation of the \
correspondence between active \
channel and selected address");
};
};
wait cycle;
};
};
// transaction-level checking and coverage
!current_packet: XYZ_packet;
event packet_in is rise('packet_valid')@pclk;
on packet_in {
current_packet = new XYZ_packet;
current_packet.addr = 'addr';
current_packet.len = 'len';
out(current_packet.get_unit());
start sample_data();
start mutex_checker();
};
sample_data() @pclk is {
if (debug_mode) {
out("Start of sampling");

Specman e Language Reference


1999-2015

273
.

Product Version 15.1


All Rights Reserved.

};
for j from 1 to current_packet.len {
wait cycle;
current_packet.data.add('data');
};
if (debug_mode) {
out("End of sampling: packet data ",
current_packet.data);
};
// Don't read parity yet
};
event packet_out is fall('packet_valid')@pclk;
expect (@packet_in => { [current_packet.len];
cycle @packet_out}) @pclk
else dut_error ("Violation of expected packet duration");
event log is @packet_out;
on packet_out {
current_packet.parity = 'parity';
// Check the last byte of the data
current_packet.kind =
('data' == current_packet.parity_calc()) ? good : bad;
if (debug_mode) {
print current_packet;
};
if (current_packet.kind == good) then {
check that 'err' == 0 else dut_error ("Err != 0 \
for good pkt");
}
else {
check that 'err' == 1 else dut_error ("Err != 1 \
for bad pkt");
};
};
event channel_data_passed;
expect (@packet_out => [1] @channel_data_passed) @pclk
else dut_error("Channel data pass and packet out \
aren't synchronous");
cover log using text = "End of package transaction" is {

Specman e Language Reference


1999-2015

274

Product Version 15.1


All Rights Reserved.

item addr : uint (bits : 2) = current_packet.addr


using illegal = (addr == 3);
item len : uint (bits : 6) = current_packet.len
using ranges={
range([0..3],"short");
range([4..15],"medium");
range([16..63],"long");
};
item kind : XYZ_kind_type = current_packet.kind ;
item err : bool = 'err' ;
};
};
'>

See Also

Units Overview on page 265

Chapter 3 Structs, Fields, and Subtypes

4.2.2

field: unit-type is instance

Purpose
Define a unit instance field

Category
Unit member

Syntax
field-name[: unit-type] is instance
Syntax Example
cpu: XYZ_cpu is instance;

Parameters
field-name

The name of the unit instance being defined.

Specman e Language Reference


1999-2015

275
.

Product Version 15.1


All Rights Reserved.

unit-type

The name of a unit type.


If the field name is the same as an existing type, you can omit the : unit-type part
of the field definition. Otherwise, the type specification is required.

Description
Defines a field of a unit to be an instance of a unit type. Units can be instantiated within other units, thus
creating a unit tree. The root of the unit tree is sys, the only predefined unit in Specman.
A unit instance has to be bound to a particular component in the DUT (an HDL path). Each unit instance
also has a unique and constant place (an e path) in the runtime data structure of an e program that is
determined during pre-run generation.

Notes

Instantiating a unit in a struct causes a compile-time error; units can only be instantiated within
another unit.
The do-not-generate operator (!) is not allowed with fields of type unit instance. Unit instances can
be created only during pre-run generation.
It is not recommended to use the physical field operator (%) with fields of type unit instance.

Example
This example creates an instance of the XYZ_router unit type in sys.
<'
extend sys {
mntr: monitor;
unit_core: XYZ_router is instance;
keep unit_core.hdl_path() =="top.router_i";
keep unit_core.debug_mode == TRUE;
setup() is also {
set_check("...", WARNING);
set_config(cover, mode, on);
};
};
'>

See Also

Units Overview on page 265

Specman e Language Reference


1999-2015

276

Product Version 15.1


All Rights Reserved.

field: unit-type on page 277

field: list of unit-type on page 280

Chapter 3 Structs, Fields, and Subtypes

4.2.3

field: unit-type

Purpose
Define a unit reference (unit pointer)

Category
Struct or unit member

Syntax
[const][!] field-name[: unit-type]
Syntax Example
extend XYZ_router{
!current_chan: XYZ_channel;
};

Parameters
const

Denotes a field that contains a constant value throughout its lifetime. See Constant Fields
on page 228.

Required unless you constrain the field to a specific unit instance with a keep constraint.
If you generate this field on the fly, you must constrain it to an existing unit instance or a
runtime error is issued.

field-name

The name of the field being defined.

unit-type

The name of a unit type.


If the field name is the same as an existing type, you can omit the : unit-type part of the
field definition. Otherwise, the type specification is required.

Specman e Language Reference


1999-2015

277
.

Product Version 15.1


All Rights Reserved.

Description
Defines a field of unit type. A field of unit type is always either NULL or a reference to a unit instance
of a specified unit type.
You can set unit pointers either declaratively or procedurally. See Unit Hierarchical References on page
269 for more information.
Note

It is not recommended to use the physical field operator (%) with fields of type unit.

Example
In the example below, the XYZ_router is extended with an ungenerated field of type XYZ_channel, a
unit type. It remains NULL until the mutex_checker() method is called. In this method the
current_chan field is used as a pointer to each of the unit instances of type XYZ_channel in the
channels list.
extend XYZ_router {
!current_chan: XYZ_channel;
mutex_checker() @pclk is {
while ('packet_valid') {
var active_channel: int = UNDEF;
for each in channels {
current_chan = it;
if '(current_chan).valid_out' {
check that active_channel == UNDEF else
dut_error ("Violation of the mutual exclusion by \
channels ", active_channel, " and ", index);
active_channel = index;
check that active_channel == 'addr' else
dut_error ("Violation of the correspondence \
between active channel and selected address");
};
};
wait cycle;
};
};
};

See Also

Unit Hierarchical References on page 269

field: unit-type is instance on page 275

field: list of unit-type on page 280

Chapter 3 Structs, Fields, and Subtypes

Specman e Language Reference


1999-2015

278

Product Version 15.1


All Rights Reserved.

4.2.4

field: list of unit instances

Purpose
Define a list field of unit instances

Category
Struct or unit member

Syntax
name:[[length-exp]]: list of unit-type is instance
Syntax Example
channels: list of XYZ_channel is instance;

Parameters
name

The name of the list being defined.

length-exp

An expression that gives the initial size for the list.

unit-type

A unit type.

is instance

Creates a list of unit instances.

Description
Defines a list field of unit instances. A list of unit instances can only be created during pre-run
generation and cannot be modified after it is generated.

Notes

List operations, such as list.add() or list.pop(), that alter the list created during pre-run generation
are not allowed for lists of unit instances.
It is not recommended to use the physical field operator (%) with lists of unit instances.

Example
This example creates a list of unit instances of type XYZ_channel in XYZ_router.

Specman e Language Reference


1999-2015

279
.

Product Version 15.1


All Rights Reserved.

<'
unit XYZ_channel {
event external_clock;
event packet_start is rise('valid_out')@sim;
event data_passed;
verilog variable 'valid_out' using wire;
data_checker() @external_clock is {
while 'valid_out' == 1 {
wait cycle;
assert 'data_out' == 'data_in';
};
emit data_passed;
};
on packet_start {
start data_checker();
};
};
unit XYZ_router {
channels: list of XYZ_channel is instance;
keep channels.size() == 3;
};
'>

See Also

field: unit-type on page 277

field: unit-type is instance on page 275

Chapter 3 Structs, Fields, and Subtypes

4.2.5

field: list of unit-type

Purpose
Define a list field of type unit

Category
Struct or unit member

Specman e Language Reference


1999-2015

280

Product Version 15.1


All Rights Reserved.

Syntax
[!]name[[length-exp]]: list of unit-type
Syntax Example
currently_valid_channels: list of XYZ_channel;

Parameters
!

Required unless you constrain the field to a specific unit instance with a keep constraint.
If you generate this field on the fly, you must constrain it to an existing unit instance or a
runtime error is issued.

name

The name of the list being defined.

length-exp

An expression that gives the initial size for the list.

unit-type

A unit type.

Description
Defines a list field of type unit. A field of unit type is always either NULL or a reference to a unit
instance of a specified unit type.
You can set unit pointers either declaratively or procedurally. See Unit Hierarchical References on page
269 for more information.
Note

It is not recommended to use the physical field operator (%) with lists of unit type.

Example
This example creates a list of unit type XYZ_channel, which is used to create a list of currently valid
channels.
<'
unit XYZ_channel {
router: XYZ_router;
};
unit XYZ_router {
channels: list of XYZ_channel is instance;
keep channels.size() == 3;
validity_checker() is {
currently_valid_channels: list of XYZ_channel;

Specman e Language Reference


1999-2015

281
.

Product Version 15.1


All Rights Reserved.

for each in channels {


if '(it).valid_in' {
currently_valid_channels.add(it);
};
};
print currently_valid_channels;
};
};
'>

See Also

Unit Hierarchical References on page 269

field: unit-type on page 277

field: unit-type is instance on page 275

Chapter 3 Structs, Fields, and Subtypes

4.3

Predefined Attributes and Methods for Any Unit

There is a predefined generic type any_unit, which is derived from any_struct. any_unit is the base
type implicitly used in user-defined unit types, so all predefined methods for any_unit are available for
any user-defined unit. The predefined methods for any_struct are also available for any user-defined
unit.
Attributes are predefined methods whose return value is constrained at generation to a particular value.
These attributes define the behavior of a unit and how you can use it. You might also find it useful in
some cases to call the attribute procedurally during the run to retrieve its value.
The predefined attributes and methods for any unit include:

agent() Unit Attribute on page 283

agent_code() on page 288

analog_agent_code() on page 289

analog_code() on page 290

e_path() on page 291

full_external_uvm_path() on page 293

full_hdl_path() on page 294

get_native_path_name() on page 296

get_parent_unit() on page 297

get_ports() on page 298

Specman e Language Reference


1999-2015

282

Product Version 15.1


All Rights Reserved.

get_ports_recursively() on page 299

hdl_path() Unit Attribute on page 300

pack_options() Unit Attribute on page 303

per_inst_cover() Unit Attribute on page 303

short_name_path(), short_name(), and short_name_style() on page 305

See Also

Unit-Related Predefined Methods for Any Struct on page 307

Unit-Related Predefined Routines on page 317

4.3.1

agent() Unit Attribute

Purpose
Maps the DUTs HDL or SystemC partitions into e code

Category
Unit attribute

Syntax
keep [unit-exp.]agent() == agent-name;
Syntax Example
router: XYZ_router is instance;
keep router.agent() == "Verilog";

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current unit
instance is assumed.

Specman e Language Reference


1999-2015

283
.

Product Version 15.1


All Rights Reserved.

agent-name One of the following predefined agent names, enclosed in double quotes. The predefined
names are case-insensitive; in other words, verilog is the same as Verilog.

For Verilog: ncvlog, verilog, mti_vlog


For VHDL: ncvhdl, vhdl, mti_vhdl
For SystemVerilog using Incisive simulator: ncsv, verilog, system_verilog, sv
For SystemVerilog using the VCS-SystemVerilog adapter: vcssv, verilog,
system_verilog, sv
For SystemVerilog using the MTI-System Verilog adapter, mti_sv
For SystemC using the Incisive simulator: ncsc, systemc, sc
For SystemC using the OSCI adapter: osci, systemc, sc

Notes

For IES-XL, you must use ncvlog, ncsv, or ncvhdl.


See Initialization File Edits Required for SystemC on page 285 for additional SystemC
requirements.

Description
Identifies the simulator used to simulate the corresponding DUT component. Specman uses the
hdl_path() and agent() constraints to create a correspondence map between the path to the external
object and the agent name defined for the unit. The agent name is used internally by Specman to pick the
right adapter (simulator interface) for each external object.
All unit instances within a unit inherit the same agent name, unless you explicitly specify another agent
name for a given instance.
The agent() definition is not needed in a single-agent environmentthat is, if the entire DUT is
described only in Verilog or only in VHDL or only in SystemC (when in master mode). However, in a
mixed-language design, you must define the agent, implicitly or explicitly, for each unit instance
associated with a non-empty hdl_path(). Also see the section below Agent Names and SystemC Slave
and Master Modes.
You can access objects from any unit instance without regard to the defined agentfor example, you
can access Verilog signals from a VHDL unit instance and vice-versa. Every object is mapped to its
external domain according to its full path, regardless of the agent of the unit from which the signal is
accessed.
When the agent() method is called procedurally, it returns the agent of the unit.

Specman e Language Reference


1999-2015

284

Product Version 15.1


All Rights Reserved.

Agent Names and SystemC Slave and Master Modes


You must specify an agent for SystemC designs when you are working in a slave mode, regardless of
whether or not the design also includes HDL modules. (When in master mode, agent() is not required
for SystemC-only designs because the master adapterOSCI or Incisive simulatorinitializes
Specman and registers itself with the corresponding agent name and alias.)
Tip

To facilitate reuse, consider always specifying agent() for all unit instances. Doing so might allow
you to use the same e code later, without changes, if you add HDL modules to the design or change
the working mode.

See Choosing Whether SystemC Controls the Simulation in the Specman Integrators Guide for a
description of the SystemC working modes.

Initialization File Edits Required for SystemC


If you use one of the following agent names, you must also edit the Specman initialization file:
systemc
sc
The default initialization file is /specman-install-dir/specman/system.specman. However, you might
also have a local .specman file that defines settings for your environment. You can edit either file. Keep
in mind that if you edit /specman-install-dir/specman/system.specman, your edits affect all users of that
installation.
The /specman-install-dir/specman/system.specman file defines the adapters for the agent names ncsc
and osci. For example:
SPECMAN_NCSC_ADAPTER="$SPECMAN_HOME/solaris/libncsc_sn_adapter.so";
SPECMAN_OSCI_ADAPTER="$SPECMAN_HOME/solaris/libosci_sn_adapter.so";

To edit the file, add a line after the above settings that maps the adapter name you are using to
$SPECMAN_NCSC_ADAPTER or $SPECMAN_OSCI_ADAPTER, whichever is appropriate, as
shown in the following table:
:

Agent Name / Simulator

Line of Code to Add to Initialization File

systemc using OSCI

SPECMAN_SYSTEMC_ADAPTER=$SPECMAN_OSCI_ADAPTER

systemc using Incisive simulator

SPECMAN_SYSTEMC_ADAPTER=$SPECMAN_NCSC_ADAPTER

sc using OSCI

SPECMAN_SC_ADAPTER=$SPECMAN_OSCI_ADAPTER

sc using Incisive simulator

SPECMAN_SC_ADAPTER=$SPECMAN_NCSC_ADAPTER

Specman e Language Reference


1999-2015

285
.

Product Version 15.1


All Rights Reserved.

Additional Notes

If you enter an unsupported agent name or if you fail to provide an agent name when it is required,
Specman issues an error message during the test phase.
Agents are bound to unit instances during the generation phase. Consequently, external objects for
which the agent() attribute is required cannot be accessed before generation from sys.setup() or from
the command line.

Example 1
In the following example, the driver instance inherits an agent name implicitly from the enclosing router
unit instance.
extend sys {
router: XYZ_router is instance;
keep router.agent() == "Verilog";
keep router.hdl_path() == "top.rout";
};
extend XYZ_router {
driver: XYZ_router_driver is instance;
};

Example 2
In this example, the signal top.rout.packet_valid is sampled using the Verilog PLI because the path
top.rout is specified as a Verilog path. In contrast, the signal top.rout.chan.mux.data_out is sampled
using a VHDL foreign interface because the closest mapped path is top.rout.chan and it is mapped as
a VHDL path.
extend sys {
router: XYZ_router is instance;
keep router.agent() == "Verilog";
keep router.hdl_path() == "top.rout";
};
unit XYZ_router {
channel: XYZ_channel is instance;
keep channel.agent() == "VHDL";
keep channel.hdl_path() == "chan";
run() is also {
print 'packet_valid';
};
};
unit XYZ_channel {
Specman e Language Reference
1999-2015

286

Product Version 15.1


All Rights Reserved.

run() is also {
print 'mux.data_out';
};
};

Example 3
The following example, which is taken from the SystemC OSCI mixed design example in
/specman-install-dir/specman/examples, shows attributes defined for the ver unit instance:
extend sys {
ver: osci_verifier is instance;

-- Unit instance

-- Identify the SystemC HDL path using global pointer:


keep ver.hdl_path() == "sn_xor->";
-- Map the HDL paths for all SystemC units to the SystemC adapter.
-- Remember that the SYSTEMC adapter name requires an edit to the
-- initialization file:
keep ver.agent() == "SYSTEMC";
-- Identify the H file that vmust be included in the stub file:
keep ver.agent_code() == {"#include 'xor.h'\n"};
run() is also {
start ver.verify();
};
};
'>

See Also

hdl_path() Unit Attribute on page 300

hdl_path() Port Attribute in the Specman Integrators Guide

agent_code() on page 288

Integrating with the OSCI Simulator in the Specman Integrators Guide

Customizing the Initialization File in the Specman Configuration Guide

Specman e Language Reference


1999-2015

287
.

Product Version 15.1


All Rights Reserved.

4.3.2

agent_code()

Purpose
Identifies external text that is automatically added to the stubs file by the write stubs command

Category
Unit attribute

Syntax
keep [unit-exp.]agent_code() == {string[; string...]};
Syntax Example
extend sys {
ver : verifier is instance;
keep ver.hdl_path() == "sn_calc->";
keep ver.agent() == "SYSTEMC";
keep ver.agent_code() == {
"#include 'calc_modules.h'";
"#include 'conv.h'";
};
};

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current unit
instance is assumed.

string

Text in an external language, for example, a SystemC statement.

Description
Defines text written in an external language that is to be written to the stubs file.
SystemC Notes
The Specman stubs file, specman.cpp, contains the references required to access the SystemC objects
bound to e ports. To compile the stubs file, the header files with the required definitions or the
definitions themselves must be provided to the write stubs command.

Specman e Language Reference


1999-2015

288

Product Version 15.1


All Rights Reserved.

To identify a header file, provide the #include declaration statement with agent_code(). You can also,
however, provide SystemC statements that identify the external object. For example, the extern
statement in the following example identifies sn_xor1 as a global variable (the sn_xor1 definition is
included in one of the SystemC files):
keep ver.agent_code() == {"extern mxor *sn_xor1;"};

If more than one unit has the agent_code attribute, the list is compiled from all units in an arbitrary
order.
Note If you create user-defined convertors, remember to also specify the header file in which your
convertors are declared in the agent_code() attribute.

Example
unit verify_struct {
...
};
extend sys {
...
ver: verify_struct is instance;
keep ver.agent_code() == {
"#include \"xor.h\" ";

-- Includes the xor.h file

"extern mxor *sn_xor1;"

-----

Additionally identifies the sn_xor1


global variable of type mxor
(pointing to the xor1 instance of
module type mxor)

};
};

4.3.3

analog_agent_code()

Purpose
Identifies text that is automatically added to the Verilog-AMS stubs file by the write stubs command

Category
Unit attribute

Specman e Language Reference


1999-2015

289
.

Product Version 15.1


All Rights Reserved.

Syntax
keep [unit-exp.]analog_agent_code() == {string[; string...]};
Syntax Example
unit verifier {
// this attribute inserts code into specman.vams
keep analog_agent_code() == {
"real a_phase;"; // aux variable
};
};

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current unit
instance is assumed.

string

Text in an external language, for example, a SystemVerilog statement.

Description
Defines auxiliary variables that are to be written to the Verilog-AMS stubs file (specman.vams).
Note

For more information on specman.vams, see Creating and Compiling the Specman

Verilog-AMS Stubs File in Specman Integrators Guide.

See Also

Inserting User Code into the Stub Files in Specman Integrators Guide

4.3.4

analog_code()

Purpose
Identifies text that is automatically added to the Verilog stubs file by the write stubs command

Category
Unit attribute

Specman e Language Reference


1999-2015

290

Product Version 15.1


All Rights Reserved.

Syntax
keep [unit-exp.]analog_code() == {string[; string...]};
Syntax Example
unit verifier {
keep analog_code() == {
"a_phase = 2*`M_PI*120M*$abstime;";
"V(top.vin) <+ 1*sin(a_phase);";
};
};

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current unit
instance is assumed.

string

Text in an external language, for example, a SystemVerilog statement.

Description
Identifies text that is automatically added to the analog block of the Verilog stubs file (specman.v) by the
write stubs command.
Note The analog_code() attribute requires a Verilog-AMS stubs file (specman.vams). For more
information on this file, see Creating and Compiling the Specman Verilog-AMS Stubs File in Specman
Integrators Guide.

See Also

Inserting User Code into the Stub Files in Specman Integrators Guide

4.3.5

e_path()

Purpose
Returns the location of a unit instance in the unit tree

Category
Predefined method for any unit

Specman e Language Reference


1999-2015

291
.

Product Version 15.1


All Rights Reserved.

Syntax
[unit-exp.]e_path(): string
Syntax Example
out("Started checking ", get_unit().e_path());

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current unit
instance is assumed.

Description
Returns the location of a unit instance in the unit tree. This method is used mainly in informational
messages.

Example
<'
unit ex_u {
run() is also {
var inst: string;
inst = get_unit().e_path();
out("ex instance: ", inst);
};
};
unit top_u {
exlist[10]: list of ex_u is instance;
};
extend sys {
top: top_u is instance;
};
'>

Result
ex
ex
ex
ex
ex

instance:
instance:
instance:
instance:
instance:

sys.top.exlist[0]
sys.top.exlist[1]
sys.top.exlist[2]
sys.top.exlist[3]
sys.top.exlist[4]

Specman e Language Reference


1999-2015

292

Product Version 15.1


All Rights Reserved.

ex
ex
ex
ex
ex

instance:
instance:
instance:
instance:
instance:

sys.top.exlist[5]
sys.top.exlist[6]
sys.top.exlist[7]
sys.top.exlist[8]
sys.top.exlist[9]

See Also

full_hdl_path() on page 294

full_external_uvm_path() on page 293

hdl_path() Unit Attribute on page 300

4.3.6

full_external_uvm_path()

Purpose
Return a full UVM path for a unit instance

Category
Predefined method for any unit

Syntax
[unit-exp.]full_external_uvm_path(): string
Syntax Example
out ("Unit is connected to ", me.full_external_uvm_path());};

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current


unit instance is assumed.

Description
Returns the external UVM path for the specified unit instance.

Specman e Language Reference


1999-2015

293
.

Product Version 15.1


All Rights Reserved.

Note The legacy method full_external_ovm_path() is also supported, but might be deprecated in the
future. The config -sim -target_ml_lib command determines whether Specman generates UVM or
OVM compliant code. The default is UVM.

Example
This example uses full_external_uvm_path() to do the connections for its instances.
extend eocb_env_u {
connect_ports() is also {
ml_uvm.connect_names(
append(me.full_external_uvm_path(), ".Rx.monitor.frame_collected_port"),
monitor.rx_frame_collected_ap.e_path());
ml_uvm.connect_names(
append(me.full_external_uvm_path(), ".Tx.monitor.frame_collected_port"),
monitor.tx_frame_collected_ap.e_path());
};
};

4.3.7

full_hdl_path()

Purpose
Return an absolute HDL path for a unit instance

Category
Predefined method for any unit

Syntax
[unit-exp.]full_hdl_path(): string
Syntax Example
out ("Mutex violation in ", get_unit().full_hdl_path());};

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current


unit instance is assumed.

Specman e Language Reference


1999-2015

294

Product Version 15.1


All Rights Reserved.

Description
Returns the absolute HDL path for the specified unit instance. This method is used mainly in
informational messages. Like the hdl_path() method, this method returns the path as originally
specified in the keep constraint, without making any macro substitutions.
Note Cadence does not recommend using full_hdl_path() during pre-run generation because of
generation dependencies: The HDL paths of the parent units may not have been generated yet.

Example
This example uses full_hdl_path() to display information about where a mutex violation has occurred.
extend XYZ_router {
!current_chan: XYZ_channel;
mutex_checker() @pclk is {
while ('packet_valid') {
var active_channel: int = UNDEF;
for each XYZ_channel(current_chan) in channels {
if '(current_chan).valid_out' {
if active_channel != UNDEF then {
out ("Mutex violation in ",
get_unit().full_hdl_path());};
active_channel = index;
};
};
wait cycle;
};
};
};

Result
Mutual exclusion violation in top.router_i

See Also

get_native_path_name() on page 296

hdl_path() Unit Attribute on page 300

e_path() on page 291

Specman e Language Reference


1999-2015

295
.

Product Version 15.1


All Rights Reserved.

4.3.8

get_native_path_name()

Purpose
Return the native HDL path for a unit instance

Category
Predefined method for any unit

Syntax
[unit-exp.]get_native_path_name(): string
Syntax Example
print get_native_path_name();

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current


unit instance is assumed.

Description
Returns the legal HDL path for the language and simulator agent being used. Examples:
ncvhdl Agent:
~/top.dff.doutreturned by full_hdl_path()
top:dff:doutreturned by get_native_path_name()
ncvlog Agent:
~/top.dff.doutreturned by full_hdl_path()
top.dff.doutreturned by get_native_path_name()
Use this method to get the actual path Specman sends to the simulator to communicate with a given
signal.
Note Do not use get_native_path_name() during pre-run generation. Using it only after the HDL
path has been generated.

Specman e Language Reference


1999-2015

296

Product Version 15.1


All Rights Reserved.

Example
unit a {
keep hdl_path() == "~/top.dff.dout";
post_generate() is also {
print full_hdl_path();
print get_native_path_name();
};
};
extend sys {
a is instance;
};

See Also

hdl_path() Unit Attribute on page 300

full_hdl_path() on page 294

e_path() on page 291

4.3.9

get_parent_unit()

Purpose
Return a reference to the unit containing the current unit instance

Category
Predefined method for any unit

Syntax
[unit-exp.]get_parent_unit(): unit type
Syntax Example
out(sys.unit_core.channels[0].get_parent_unit());

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current


unit instance is assumed.

Specman e Language Reference


1999-2015

297
.

Product Version 15.1


All Rights Reserved.

Description
Returns a reference to the unit in which current instance was created.
Note The return reference is to the unit in which current instance was created, and not the unit in
which this calling unit is sitting under in the instance hierarchy. That means that if you assign or copy an
instance to a specific pointer, get_parent_unit() returns a reference to the unit under which this instance
was originally created.

Example
cmd-prompt> out(sys.unit_core.channels[0].get_parent_unit())
XYZ_router-@2

See Also

get_unit() on page 307

get_enclosing_unit() on page 312

try_enclosing_unit() on page 315

4.3.10

get_ports()

Purpose
Returns the list of port instances of a given unit

Category
Predefined method for any unit

Syntax
[unit-exp.]get_ports(): list of any_port
Syntax Example
sys.u1.u2.get_ports()

Specman e Language Reference


1999-2015

298

Product Version 15.1


All Rights Reserved.

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current unit
instance is assumed.

Description
Returns the list of port instances for the given unit.

See Also

get_ports_recursively() on page 299

4.3.11

get_ports_recursively()

Purpose
Returns a list of port instances for the given unit, and in all units under it

Category
Predefined method for any unit

Syntax
[unit-exp.]get_ports_recursively(): list of any_port
Syntax Example
sys.get_ports_recursively()

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current unit
instance is assumed.

Description
Returns a list of port instances for the given unit, and in all units under it.

Specman e Language Reference


1999-2015

299
.

Product Version 15.1


All Rights Reserved.

Example
unit u1 {
p1 : out simple_port of int is instance;
p2 : in simple_port of int is instance;
u2 is instance;
};
unit u2 {
p3 : in event_port is instance;
};
extend sys {
u1 is instance;
run() is also {
print u1.get_ports();
// will print sys.u1.p1 and sys.u1.p2 - a list of size 2
print u1.get_ports_recursively();
// will print sys.u1.p1, sys.u1.p2 and sys.u2.p3 - a list of size 3
};
};

See Also

get_ports() on page 298

4.3.12

hdl_path() Unit Attribute

Purpose
Define a relative HDL path for a unit instance

Category
Unit attribute

Syntax
keep [unit-exp.]hdl_path() == string;
Syntax Example
keep my_cpu.hdl_path() == "~/top";

Specman e Language Reference


1999-2015

300

Product Version 15.1


All Rights Reserved.

Parameters
unit-exp

An expression that returns a unit instance. If no expression is specified, the current


unit instance is assumed.

Description
Returns the HDL path of a unit instance. The most typical use of this method is to bind a unit instance to
a particular component in the DUT hierarchy. Binding an e unit or unit instance to a DUT component
lets you reference signals within that component using relative HDL path names. Regardless of where
the DUT component is instantiated in the final integration, the HDL path names are still valid. The
binding of unit instances to HDL components is a part of the pre-run generation process and must be
done in keep constraints.
Although absolute HDL paths are allowed, relative HDL paths are recommended if you intend to follow
a modular verification strategy.
This method always returns an HDL path exactly as it was specified in constraints. If, for example, you
use a macro in a constraint string, then hdl_path() returns the original and not substituted string.

Notes

All instances of the same unit should be bound to the same kind of HDL components.
Note You can bind different instances of the same unit to different DUT components if the
components have the same functional signals. The DUT components can be written in different
languages, such as Verilog, VHDL, SystemC, and so on.

You cannot constrain the HDL path for sys.


When you run Specman standalone, unit relative paths are not concatenated with full HDL paths of
the unit instances. There is no workaround for this.
To prevent Specman from concatenating the path of the parent unit to the child unit, use
keep unit.hdl_path() == "~/";

For example:
<'
unit memory{
p: simple_port of int is instance;
keep bind(p,external);
keep p.hdl_path() == "/memory/sig"; // the path is /memory/sig
// not /top/memory/sig
};
unit my_cpu {
Specman e Language Reference
1999-2015

301
.

Product Version 15.1


All Rights Reserved.

p: simple_port of int is instance;


keep bind(p,external);
keep p.hdl_path() == "sig";

//

the path is /top/sig

memory is instance;
keep memory.hdl_path() == "~/"; // prevents concatenation of the
// hdl path
};
extend sys {
my_cpu is instance;
keep my_cpu.hdl_path() == "~/top";
};
'>

Example 1
This example shows how you can use relative paths in lower-level instances in the unit instance tree. To
create the full HDL path of each unit instance, its HDL path is prefixed with the HDL path of its parent
instance. In this example, because the HDL path of sys is , the full HDL path of unit_core is
top.router_i. The full HDL path of extra_channel is top.router_i.chan3.
extend sys {
unit_core: XYZ_router is instance;
keep unit_core.hdl_path() == "top.router_i";
};
extend XYZ_router {
extra_channel: XYZ_channel is instance;
keep extra_channel.hdl_path() == "chan3";
};

Example 2
This example shows how hdl_path() returns the HDL path exactly as specified in the constraint. Thus
the first print action prints `TOP.router_i. The second print action, in contrast, accesses
top.router_i.clk.
verilog import macros.v;
extend sys {
unit_core: XYZ_router is instance;
keep unit_core.hdl_path() == "TOP.router_i";
run() is also {
print unit_core.hdl_path();
Specman e Language Reference
1999-2015

302

Product Version 15.1


All Rights Reserved.

print '(unit_core).clk';
};
};

Result
cmd-prompt> test
...
Starting the test ...
Running the test ...
unit_core.hdl_path() = "TOP.router_i"
'top.router_i.clk' = 0

See Also

HDL Paths and Units on page 268

full_hdl_path() on page 294

e_path() on page 291

hdl_path() Port Attribute in the Specman Integrators Guide

HDL Object Names in the Specman Integrators Guide

4.3.13

pack_options() Unit Attribute

Note The pack_options() attribute for units uses the same syntax and follows the same rules as the
pack_options() attribute for ports. For more information about this attribute, see pack_options() in the
Specman Integrators Guide.

4.3.14

per_inst_cover() Unit Attribute

Purpose
For coverage data to be used in Enterprise Manager, sets the default coverage collection behavior for
cover entities of a unit instance

Category
Unit attribute

Specman e Language Reference


1999-2015

303
.

Product Version 15.1


All Rights Reserved.

Syntax
keep [soft] [relative-unit-path.]per_inst_cover() == [DEFAULT | YES | NO]
Syntax Example
keep u22.per_inst_cover() == NO

Parameters
DEFAULT The unit inherits the coverage data collection behavior of its parent unit in the unit tree.
For coverage specified using per_unit_instance=sys, DEFAULT and YES are identical.
YES

Instance-basedCoverage entities in units that have no explicit per_unit_instance


declaration are collected per instance for Enterprise Manager.

NO

Type-basedCoverage entities in units that have no explicit per_unit_instance


declaration are collected per type.

Description
Sets the default coverage data collection behavior for all cover entitiesgroups, checks, and blocksof
a unit instance.

Example
extend sys {
u1 is instance;
u21: u2 is instance;
u22: u2 is instance;
// Disable per-instance collection for sys.u22:
keep u22.per_inst_cover() == NO;
run() is also {
for i from 1 to 10 {
u1.sample_cov();
u21.sample_cov(u1.s);
u22.sample_cov(u1.s);
};
};
};

Specman e Language Reference


1999-2015

304

Product Version 15.1


All Rights Reserved.

4.3.15

short_name_path(), short_name(), and


short_name_style()

Purpose
short_name() defines short names for units.
short_name_path() returns the short-name path for a unit.
short_name_style() returns the color of short names for a unit

Category
Unit predefined methods

Syntax
short_name_path(plain: bool): string
short_name(): string
short_name_style(): vt_style

Description
The short_name_path() method of any_unit returns the path of short names defined for a given unit.
Using short names makes messages shorter and easier to read. For example, in the following message,
AHB_0 Master_1 is the string returned by the message action calling short_name_path().
[123000] AHB_0 MASTER_1: Received first part of transaction-@33

The plain Boolean parameter for short_name_path() determines whether the string of short names
returned is colored or not.

When plain is FALSE (the default), the returned string is the concatenation of short names of all the
units in the path, with short name styles being applied to them.
When plain is TRUE, the returned string is the concatenation of short names of all the units in the
path, but short name styles are not applied, which means the string is not colored.

Getting the plain (non-colored) version of the string lets you, for example, use operations on the string
such as str_len() to customize message formatting. Such operations give improper results on colored
strings. Cadence recommend to use the string returned from short_name_path(TRUE) for such
purposes.

Specman e Language Reference


1999-2015

305
.

Product Version 15.1


All Rights Reserved.

By default, short_name() returns an empty string. So, to specify the desired short name for the unit, you
must extend this method. For example
extend vr_ahb_env {
evc_name: vr_ahb_name;

// e.g. AHB_0 etc.

short_name(): string is only {


return evc_name.to_string();
};
};
extend vr_usb_agent {
index: int;

// The index in some big list

short_name(): string is only {


return dec("USB agent[", index, "]");
};
};

The short_name_path() method does the following:


1.

Concatenates all of the non-empty short_name() strings along the path from sys to the unit.

2.

Appends a blank separator to each string.

3.

If the result is not empty, returns the result (in non-colored text if short_name_path(TRUE) is
specified). Otherwise, it returns something like vr_xbus_env_u-@55.

You can return the color that you want to use when displaying short names for a unit by calling the
short_name_style() method. The default color for short names is BLACK. To change the color, you
specify the new color as a return value for short_name_style(). For example:
extend MASTER vt_ahb_agent {
short_name_style(): vt_style is only [return DARK_BLUE];
};

You can specify the color using the Verification Toolkit (VT) color name, such as DARK_BLUE, or by
its RGB color code, such as #000080 for dark blue.

See Also

Specifying a Short Path in Creating e Testbenches

show_styles() in Specman Deprecation and Backwards Compatability

get_color_code() in Specman Deprecation and Backwards Compatability

text_style() in Specman Deprecation and Backwards Compatability

Specman e Language Reference


1999-2015

306

Product Version 15.1


All Rights Reserved.

4.4

Unit-Related Predefined Methods for Any Struct

The predefined methods for any_struct include:

get_unit() on page 307

get_all_units() on page 310

get_enclosing_unit() on page 312

try_enclosing_unit() on page 315

set_unit() on page 316

See Also

Predefined Attributes and Methods for Any Unit on page 282

Unit-Related Predefined Routines on page 317

Predefined Methods of Any Struct or Unit on page 1176

4.4.1

get_unit()

Purpose
Return a reference to a unit

Category
Predefined method of any struct

Syntax
[exp.]get_unit(): unit type
Syntax Example
out ("Mutex violation in ", get_unit().full_hdl_path());};

Parameters
exp

An expression that returns a unit or a struct. If no expression is specified, the current struct
or unit is assumed.

Specman e Language Reference


1999-2015

307
.

Product Version 15.1


All Rights Reserved.

Description
When applied to an allocated struct instance, this method returns a reference to the parent unitthe unit
to which the struct is bound. When applied to a unit, it returns the unit itself.
Any allocated struct instance automatically establishes a reference to its parent unit. If this struct is
generated during pre-run generation it inherits the parent unit of its parent struct. If the struct is
dynamically allocated by the new or gen action, then the parent unit is inherited from the struct the
enclosing method belongs to. See Example 3 on page 309 for an illustration of this point.
This method is useful when you want to determine the parent unit instance of a struct or a unit. You can
also use this method to access predefined unit members, such as hdl_path() or full_hdl_path(). To
access user-defined unit members, use get_enclosing_unit(). See Example 1 on page 308 for an
illustration of this point.

Example 1
This example shows that get_unit() can access predefined unit members, while get_enclosing_unit()
must be used to access user-defined unit members.
struct instr {
%opcode
%op1
kind

--

: cpu_opcode ;
: reg ;
: [imm, reg];

post_generate() is also {
get_unit().print_msg() ; -- COMPILE-TIME ERROR
get_enclosing_unit(XYZ_cpu).print_msg();
out("Destination for this instruction is ",
get_unit().hdl_path()) ;
};

};
unit XYZ_cpu {
instrs[3] : list of instr;
print_msg() is {out("Generating instruction for \
XYZ_cpu...");};
};
extend sys {
cpu1: XYZ_cpu is instance;
keep cpu1.hdl_path()=="TOP/CPU1";
};
'>

Specman e Language Reference


1999-2015

308

Product Version 15.1


All Rights Reserved.

Result
cmd-prompt> gen
Doing setup ...
Generating the test using seed 1...
Generating instruction for XYZ_cpu...
Destination for this instruction is TOP/CPU1
Generating instruction for XYZ_cpu...
Destination for this instruction is TOP/CPU1
Generating instruction for XYZ_cpu...
Destination for this instruction is TOP/CPU1
cmd-prompt>

Example 2
The first call to get_unit() below shows that the parent unit of the struct instance p is sys. The second
call shows that the parent unit has been changed to XYZ_router.
cmd-prompt> var p: XYZ_packet = new
cmd-prompt> out(p.get_unit())
sys-@0
cmd-prompt> p.set_unit(sys.unit_core)
cmd-prompt> out(p.get_unit())
XYZ_router-@1

Example 3
In this example, the trace_inject() method displays the full HDL path of the XYZ_dlx unit (not the
XYZ_tb unit) because instr_list is generated by the run method of XYZ_dlx.
extend sys {
tb: XYZ_tb is instance;
keep tb.hdl_path()=="TOP/tb";
};
unit XYZ_tb {
dlx: XYZ_dlx is instance;
keep dlx.hdl_path()=="dlx_cpu";
!instr_list: list of instruction;
debug_mode: bool;
};
unit XYZ_dlx {
run() is also {
gen sys.tb.instr_list keeping { .size() < 30;};
};
};
extend instruction {
trace_inject() is {
if get_enclosing_unit(XYZ_tb).debug_mode == TRUE {
Specman e Language Reference
1999-2015

309
.

Product Version 15.1


All Rights Reserved.

out("Injecting next instruction to ",


get_unit().full_hdl_path());
};
};
};

Result
cmd-prompt> sys.tb.instr_list[0].trace_inject()
Injecting next instruction to TOP/tb.dlx_cpu

See Also

get_parent_unit() on page 297

get_enclosing_unit() on page 312

try_enclosing_unit() on page 315

4.4.2

get_all_units()

Purpose
Return a list of instances of a specified unit type

Category
Predefined pseudo-method of any struct

Syntax
get_all_units(unit-type: type-name): list of unit instances
Syntax Example
print get_all_units(XYZ_channel);

Parameter
unit-type

The name of a unit type. The type must be defined or an error occurs.

Specman e Language Reference


1999-2015

310

Product Version 15.1


All Rights Reserved.

Description
This pseudomethod receives a unit type as a parameter and returns a list of instances of this unit type as
well as any unit instances contained within each instance.

Example
This example uses get_all_units() to print a list of the instances of XYZ_router. Note that the display
also shows that this instance of XYZ_router contains channels, which is a list of three unit instances.
<'
unit XYZ_router {
channels: list of XYZ_channel is instance;
keep channels.size() == 3;
keep for each in channels {
.hdl_path() == append("chan", index);
.router == me
};
};
unit XYZ_channel {
router:XYZ_router;
};
extend sys {
router:XYZ_router is instance;
run() is also {
print get_all_units(XYZ_router);
};
};
'>

Result
Specman > test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
get_all_units(XYZ_router) =
item
type
channels
--------------------------------------------------------------0.
XYZ_router (3 items)

Specman e Language Reference


1999-2015

311
.

Product Version 15.1


All Rights Reserved.

See Also

Predefined Attributes and Methods for Any Unit on page 282

get_parent_unit() on page 297

get_unit() on page 307

get_enclosing_unit() on page 312

try_enclosing_unit() on page 315

set_unit() on page 316

4.4.3

get_enclosing_unit()

Purpose
Return a reference to the unit in which the struct was created

Category
Predefined pseudo-method of any struct

Syntax
get_enclosing_unit(unit-type: type-name): unit instance
Syntax Example
unpack(p.get_enclosing_unit(XYZ_router).pack_config,
'data', current_packet);

Parameters
unit-type

The name of a unit type or unit subtype.

Description
Returns a reference to the unit in which the struct was created, allowing you to access fields of the parent
unit in a typed manner.
You can use the parent unit to store shared data or options such as packing options that are valid for all
its associated subunits or structs. Then you can access this shared data or options with the
get_enclosing_unit() method.

Specman e Language Reference


1999-2015

312

Product Version 15.1


All Rights Reserved.

Notes

The unit type is recognized according to the same rules used for the is a operator. This means, for
example, that if you specify a base unit type and there is an instance of a unit subtype, the unit subtype
is found.
If a unit instance of the specified type is not found, a runtime error is issued.
The return reference is to the unit in which the struct was created, and not the unit in which this
calling unit is sitting under in the instance hierarchy. That means that if you assign or copy an instance
to a specific pointer, get_enclosing_unit() will still return a reference to the unit under which this
instance was originally created.

Example 1
In the following example, get_enclosing_unit() is used to print fields of the nearest enclosing unit
instances of type XYZ_cpu and tbench. Unlike get_unit(), which returns a reference only to its
immediate parent unit, get_enclosing_unit() searches up the unit instance tree for a unit instance of the
type you specify. A runtime error is issued unless an instance of type XYZ_cpu and an instance of
type tbench are found in the enclosing unit hierarchy.
struct instr {
%opcode
%op1
kind

: cpu_opcode ;
: reg ;
: [imm, reg];

post_generate() is also {
out("Debug mode for CPU is ",
get_enclosing_unit(XYZ_cpu).debug_mode);
out("Memory model is ",
get_enclosing_unit(tbench).mem_model);
};
};
unit XYZ_cpu {
instr: instr;
debug_mode: bool;
};
unit tbench {
cpu: XYZ_cpu is instance;
mem_model: [small, big];
};
extend sys {
tb: tbench is instance;
};

Specman e Language Reference


1999-2015

313
.

Product Version 15.1


All Rights Reserved.

Result
cmd-prompt> gen
Doing setup ...
Generating the test using seed 1...
Debug mode for CPU is FALSE
Memory model is small
cmd-prompt>

Example 2
extend XYZ_router {
pack_config:pack_options;
keep pack_config == packing.low_big_endian;
};

Result
cmd-prompt> var p: XYZ_packet = new
cmd-prompt> print p.data
p.data = (empty)
cmd-prompt> out(p.get_unit())
sys-@0
cmd-prompt> p.set_unit(sys.unit_core)
cmd-prompt> out(p.get_unit())
XYZ_router-@1
cmd-prompt> show unpack(
p.get_enclosing_unit(XYZ_router).pack_config, data, p)
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0|
|
0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 0|
|
data
|
|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0|
+
|
|0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0
+
|
|
|

+0

+32

See Also

get_unit() on page 307

set_unit() on page 316

try_enclosing_unit() on page 315

Specman e Language Reference


1999-2015

314

Product Version 15.1


All Rights Reserved.

get_parent_unit() on page 297

4.4.4

try_enclosing_unit()

Purpose
Return a reference to nearest unit instance of specified type or NULL

Category
Predefined method of any struct

Syntax
try_enclosing_unit(unit-type: type-name): unit instance
Syntax Example
var MIPS := source_struct().try_enclosing_unit(MIPS);

Parameters
exp

An expression that returns a unit or a struct. If no expression is specified, the current


struct or unit is assumed.
Note If try_enclosing_unit() is called from within a unit of the same type as exp,
it returns the present unit instance and not the parent unit instance.

unit-type

The name of a unit type or unit subtype.

Description
Like get_enclosing_unit(), this method returns a reference to the nearest higher-level unit instance of
the specified type, allowing you to access fields of the parent unit in a typed manner.
Unlike get_enclosing_unit(), this method does not issue a runtime error if no unit instance of the
specified type is found. Instead, it returns NULL. This feature makes the method suitable for use in
extensions to global methods such as dut_error_struct.write(), which may be used with more than one
unit type.

Example
<'
Specman e Language Reference
1999-2015

315
.

Product Version 15.1


All Rights Reserved.

extend dut_error_struct {
write() is also {
var MIPS := source_struct().try_enclosing_unit(MIPS);
if MIPS != NULL then {
out("Status of ", MIPS.e_path(),
" at time of error:");
MIPS.show_status();
};
};
};
'>

See Also

get_unit() on page 307

get_enclosing_unit() on page 312

get_parent_unit() on page 297

4.4.5

set_unit()

Purpose
Change the parent unit of a struct

Category
Predefined method of any struct

Syntax
[struct-exp.]set_unit(parent: exp)
Syntax Example
p.set_unit(sys.unit_core)

Parameters
struct-exp An expression that returns a struct. If no expression is specified, the current struct is assumed.
parent

An expression that returns a unit instance.

Specman e Language Reference


1999-2015

316

Product Version 15.1


All Rights Reserved.

Description
Changes the parent unit of a struct to the specified unit instance.

Note
This method does not exist for units because the unit tree cannot be modified.

Example
cmd-prompt> var p: XYZ_packet = new
cmd-prompt> out(p.get_unit())
sys-@0
cmd-prompt> p.set_unit(sys.unit_core)
cmd-prompt> out(p.get_unit())
XYZ_router-@1

4.5

Unit-Related Predefined Routines

The predefined routines that are useful for units include:

set_config_max() on page 317

4.5.1

set_config_max()

Purpose
Increase values of numeric global configuration parameters

Category
Predefined routine

Syntax
set_config_max(category: keyword, option: keyword, value: exp [, option: keyword, value: exp...])
Syntax Example
set_config_max(memory, gc_threshold, 100m);

Specman e Language Reference


1999-2015

317
.

Product Version 15.1


All Rights Reserved.

Parameters
category

Is one of the following: cover, gen, memory, and run.

option

The valid cover options are:


absolute_max_buckets, described in configure cover in the
Specman Command Reference.
The valid gen options are:

absolute_max_list_size
max_depth
max_structs
These options are described in configure gen in the Specman Command
Reference.

The valid memory options are:


gc_threshold
gc_increment
max_size
absolute_max_size
These options are described in configure memory in the Specman
Command Reference.

The valid run options are:

value

tick_max, described in configure run in the Specman Command


Reference.

The valid values are different for each option and are described in the
Specman Command Reference.

Description
Sets the numeric options of a particular category to the specified maximum values.
If you are creating a modular verification environment, it is recommended to use set_config_max()
instead of set_config() in order to avoid possible conflicts that may happen in an integrated
environment. For example, if two units are instantiated and both of them attempt to enlarge Specman
configuration value of absolute_max_size then the recommended way to it is via set_config_max, so
that no unit decrements the value set by another one.

Example
<'
Specman e Language Reference
1999-2015

318

Product Version 15.1


All Rights Reserved.

extend sys {
setup() is also {
set_config_max(memory, gc_threshold, 100m);
};
};
'>

See Also

Predefined Attributes and Methods for Any Unit on page 282

Unit-Related Predefined Methods for Any Struct on page 307

The setup() Method of sys on page 1161

Specman e Language Reference


1999-2015

319
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

320

Product Version 15.1


All Rights Reserved.

Template Types

Template types in e let you define generic structs and units that are parameterized by type, similar to
C++ templates. You can later instantiate them, giving specific types as actual parameters.
The following sections describe the principles and usage of the Specman templates feature:

Defining a Template Type on page 321

Extending a Template on page 326

Instantiating a Template Type on page 328

Template Errors on page 330

Template Limitations on page 332

Templates Versus Macros on page 332

Note Because units are a special case of structs, you can define templates for both structs and units.
In general, a template instance is a struct type. Provided it is legal, a template instance becomes a struct
as soon as it is referenced. It can be used in any context, and in any way in which a regular struct can be
used.

5.1

Defining a Template Type

To define a template, use the template statement.

Syntax
[package] template (struct|unit) template-name of (param-list)
[like base-type] {[member;...]}

Specman e Language Reference


1999-2015

321
.

Product Version 15.1


All Rights Reserved.

Parameters:
package

Denotes package access restriction to this template.

struct or unit

Denotes whether the instances of this template are structs or units.

template-name

Name of the template.

param-list

List of comma-separated template parameters, in form <[tag']type> [:type-category]


[=default ], where:
tag'

A legal name in e.

type-category

If specified, denotes a category of types to which this template


parameter is allowed to belong. (See About Template
Parameter Type-Categories on page 323.)

default

If specified, must be a legal type name in e. It may also be


derived from one the previous parameters. (See About
Template Parameter Defaults on page 323.

Parenthesis are optional if the template has only one parameter, and it has no category
and no default. Otherwise, the parameters must be enclosed in parenthesis and
separated by commas.
base-type

Base struct from which instances of the template inherit.


The base type can itself be parameterized over one or more of the template
parameters, in which case each template instance inherits from a different type (see
About Template Base Type on page 324).

member;...

Body of the template, which contains fields, methods, events, and other struct
members. The template parameters can be used within the members as appropriate
(see About the Template Body on page 325).

Description
Notes

Template names share the namespace with types, so these names cannot be the same as any other
type or template name in the same package. Templates are treated the same as types with respect to:

Name resolutionSee Type Name Resolution Rules and Packages as Namespaces for Types
in Creating e Testbenches
Access control Controlling Access with Packages in Creating e Testbenches

Specman e Language Reference


1999-2015

322

Product Version 15.1


All Rights Reserved.

In a template definition, it is possible to bound parameters to specific categories of types, to restrict


instantiating the template to certain parameter types only; other instances are made explicitly invalid.

About Template Type Parameters


A type parameter name has the form <[tag']type>. It can be any legal type in e. When the template is
instantiated, a specific type is substituted for each such parameter.
A type parameter can occur anywhere inside the template body where a type is allowed or expected. In
Example 1 on page 325, both <key'type> and <value'type> are used to specify the types of fields,

method parameters, and method return values.


About Template Parameter Type-Categories
The type-category, if specified, denotes a category of types to which this template parameter is allowed
to belong.
The following table lists supported predefined categories:
Category name

Explanation

struct

struct type, including unit, when subtype, or template


instance

list

list type

scalar

scalar type, including numeric and enumerated types

numeric

numeric type

enum

enumerated type

port

port type

If both type-category and default are specified, and if default is defined as a specific type (rather than
depending on a previous parameter), then the default type must comply with the category.
About Template Parameter Defaults
Template parameters can be given defaults. When the template is instantiated and a parameter with a
default is omitted, the default is used as the actual parameter for the instance. Parameters with defaults
must appear at the end of the parameter list. Specifying a default followed by a parameter without a
default generates an error at compile time.
For example, the following template type specifies a default type of int for the second parameter, and a
default type of string for the third parameter:

Specman e Language Reference


1999-2015

323
.

Product Version 15.1


All Rights Reserved.

template struct t of (<firsttype>, <secondtype> = int,


<thirdtype> = string) {
...
};

The default for a parameter can also be derived from a previous parameter. For example, in the
following template the default type of the second parameter is equal to the type of the first parameter,
and the default type of the third parameter is a list of the first parameter type:
template struct t1 of (
<firsttype>,
<secondtype> = <firsttype>,
<thirdtype> = list of <firsttype>) {
...
};

About Template Base Type


A template base type is a template type from which other template types can be derived. A simple way
to create a template base type is to specify a concrete type as the base type, so that all of the template
instances inherit from the same type. The base type can be a regular struct or an instance of another
template. For example:
struct s { ... };
template struct t1 of <type> like s { ... };
template struct t2 of <type> like t1 of int { ... };

In this example, struct s is a base type, template t1 is derived from struct s, and template t2 is derived
from t1. Both templates inherit from struct s.
Often, the base type itself is parameterized over the template parameters. For example, one of the type
parameters can be used as the base type, as follows:
template struct s of <sometype> like <sometype> {...};

The rules for specifying base types for regular structs also apply to template base types. In particular, a
unit template cannot inherit from a non-unit struct, and vice versa. For example, the following code is
illegal:
struct some_struct {...};
template struct struct_tmp1 of <type> {...};
template unit unit_tmp1 of <type> like some_struct { ...};
template unit other_unit_tmp1 of <type> like struct_tmp1 of <type> {...};

Like regular structs and units, the default base type for struct templates is any_struct, and the default
base type for unit templates is any_unit.

Specman e Language Reference


1999-2015

324

Product Version 15.1


All Rights Reserved.

About the Template Body


The template body consists of struct members. It can contain fields, methods, events, coverage groups,
constraints, and any other kind of struct members. You can use a template parameter wherever a type is
allowed. You can also define a when subtype within a template in the same way that you define a when
subtype within a regular struct. The following is a template body example:
Template Body Example
template struct packet of (<kind'type>, <data'type>:numeric) {
size: uint;
data1: <data'type>;
data2: <data'type>;
kind: <kind'type>;
keep size < 256;
sum_data(): <data'type> is {
return data1 + data2;
};
};

Example 1

Template Definition Example

Assume that we need to define a generic map class, which holds key/value pairs. While values are
allowed to be of any type, keys must only be scalars. This can be done as follows:
package template struct pair of (<key'type>: scalar, <value'type>) {
key: <key'type>;
value: <value'type>;
};
template struct map of (<key'type>: scalar, <value'type>) {
private entries: list (key: key) of pair of (<key'type>, <value'type>);
get(key: <key'type>): <value'type> is {
var entry := entries.key(key);
if entry != NULL then {
result = entry.value;
};
};
put(key: <key'type>, value: <value'type>) is {
var entry := entries.key(key);
if entry == NULL then {
entry = new with {
.key = key;
};
entries.add(entry);
};
entry.value = value;
};
};
Specman e Language Reference
1999-2015

325
.

Product Version 15.1


All Rights Reserved.

Note that with this template, an attempt to use an instance such as


map of (string, int)

will lead to a compilation error because string is not a scalar type.

5.2

Extending a Template

You can extend a template (similar to extending a struct), using the template extend construct.

Syntax
template extend template-name of (param-list) {[member;...]}

Parameters
template-name

Name of the template (struct or unit) being extended. The template name may be
qualified, and a previous template declaration must already exist.

param-list

List of comma-separated template parameters in either of two forms:

<[tag']type> [:type-category]

type-name

where:
tag'

A legal name in e.

type-category

If specified, denotes a category of types to which this template


extension applies. (See About Template Parameter
Type-Categories on page 323.)

type-name

Specific type name.

This template extension will apply to a given template instance if and only if all type
parameters comply with these specifications: Category compliance where
type-category is specified, or the specific type where type-name is specified. Other
template instances may still be created or exist, but the members declared in this
specific template extension will not apply to them.
The number of parameters must be equal to the number of parameters in the original
template declaration. If there is only one parameter, and it has no category
specification, parentheses may be omitted. Tags may be different from the original
declaration, as long as they are unique between them (in case of two or more
parameters).

Specman e Language Reference


1999-2015

326

Product Version 15.1


All Rights Reserved.

member;...

The extension body, i.e., the members added or changed in the template. It can
include new fields, methods, etc., or it can change methods by using is only, is also,
and so on.

In a template extension, it is possible to bound parameters to specific types or categories of types, thus
defining a template specialization in a more general way than extending a single specific template
instance.
The changes and additions defined in a template extension body apply to all instances of the template
(whose parameters comply with the specified types and categories), as well as to all sub-types of those
instances, both instances that are already instantiated by the time of introducing the template extend, and
those that are not yet.
For example, given the following
template struct t1 of <type> {
x: int;
foo() is {
...
};
};
template struct t2 of <type> like t1 of <type> {
...
};
struct s like t1 of int {
...
};

the following template extend adds the field y and overrides the method foo() in all the instances of
both t1 and t2, and also in s.
template extend t1 of <type> {
y: int;
foo() is only {
...
};
};

Example 2

Template Extension

This template extension may follow the template definition (see Template Body Example on page 325),
and it applies only to those instances of template packet whose first parameter is an enumerated type
(we are assuming that it has an item red). It does not apply to instances whose first parameter is a
different type.
template extend packet of (<kind'type>: enum, <data'type>) {
Specman e Language Reference
1999-2015

327
.

Product Version 15.1


All Rights Reserved.

when red {
red_data: <data'type>;
};
};

Notes

In a template extension, it is possible to bound parameters to specific types or categories of types.


This allows definition of template specialization in a more general way than extending a single
specific template instance.
You cannot bound all parameters to a specific type. In this case, extend a specific template instance
using a regular extend statement rather than template extend.

5.3

Instantiating a Template Type

Use the following syntax to instantiate a template:


template-name of ( actual-param-list )
The actual-param-list is a comma-separated list of actual parameters for the template. For each type
parameter, you must specify a legal type name. If a template parameter has a default, you can omit it
from the actual parameter list, as long as it is at the end of the list. If a template has only one parameter,
you can omit the parenthesis around the single actual parameter.
A template instance creates a new struct by substituting an actual parameter for the corresponding
template parameter within the template body, including within the bodies of any template extensions.
This substitution also occurs in the definition of the base type. Because a template instance becomes a
struct, its name can be used anywhere a struct name is allowed or expected.
Notes

All instances of a template are considered to be defined where the template is defined, regardless of
where they are instantiated. This applies in particular to name resolution and access control issues
(see Type Name Resolution Rules and Packages as Namespaces for Types in Creating e Testbenches).
The specified actual parameter must comply with type categories specified for each parameter in the
original template definition, or a compilation error is produced.
If the template has one or more extensions, each one of them applies to this template instance only
if all actual parameters comply with types or type categories specified for the corresponding
parameters in that extension.

In general, you can use any legal type as an actual type parameter, including another template instance,
or another instance of the same template. For example, given the map template in Example 1 on
page 325, you can create the following instances:
map of (int, int)
Specman e Language Reference
1999-2015

328

Product Version 15.1


All Rights Reserved.

map of (uint, s2)


map of (color, map of (string, int))

However, creating an instance such as map of (s1, s2), where s1 is a struct type, is illegal, because it does
not comply with the category specified for the first parameter - scalar.
Given the packet template in Example 2 on page 327, you can create the following instances:
packet of (color, int)
packet of (color, uint(bits: 64))
packet of (int, int) //Note that the extension does not apply to it,
because the first parameter is not an enumerated type.

The following instance is illegal, because the code in the template body implies that <kind'type> must be
an enum that has the value red:
packet of ([green, blue], int)

Any two instances of a template are considered the same instance if their actual parameters refer to
exactly the same types, even if they are different syntactically. For example, the following fields, x and
y, have the same type:
#define N 32;
type color: [red, green];
struct s {
x: packet of (color, int(bits: 64));
y: packet of (color, int(bits: N*2));
};

5.3.1

Template Subtype Instances

If a template definition includes when subtypes, you can refer to it in the same way you refer to regular
when subtypes. For example, given the packet template in Example 2 on page 327, the following is a
legal type name, because it denotes the red'kind subtype of the packet of (color, int) template instance.
red packet of (color, int)

This type name denotes the <kindred> subtype of the pack of color template instance.
You can also extend a when subtype of a template instance, as you would a template instance. For
example:
extend red packet of color {
...
};

Specman e Language Reference


1999-2015

329
.

Product Version 15.1


All Rights Reserved.

5.3.2

Forward References

The rules for forward referencing of template definitions are the same as for type definitions. A template
definition can refer to types, fields, and so on that are not yet defined at that point, but are defined later
in the same translation unit, that is, in a single module or a group of modules that are translated together
due to cyclic import.
Similarly, a struct or template definition can refer to instances of templates that are defined later in the
same translation unit. In particular, a template definition, like a struct definition, can refer to itself in its
own body.
For example, the following code is legal:
template struct t1 of <type> {
x: t2 of list of <type>;
};
template struct t2 of <type> {
y: t1 of s;
};
struct s {
f(): list of t1 of int is { ... };
};

5.4

Template Errors

Certain kinds of compilation errors are discovered and reported when processing the template definition.
Others are discovered and reported upon specific instantiations.
The following sections describe the possible error situations related to templates:

Template Definition Errors on page 330

Template Instantiation Errors on page 331

Run-Time Errors on page 332

5.4.1

Template Definition Errors

Two kinds of compilation errors are discovered and reported when a template definition is processed:

Syntax errors

Semantic errors related to type names within the template definition

If these kinds of errors are found within a template definition, they are reported in the same way as when
they are in a regular struct definition. In particular, each error message refers to the source line where the
error is present.

Specman e Language Reference


1999-2015

330

Product Version 15.1


All Rights Reserved.

5.4.2

Template Instantiation Errors

Most kinds of semantic errors are discovered when the template is instantiated. Some instances of the
same template can be legal, while others can be illegal and lead to semantic errors, except for those
semantic errors related to type names used in the code (Template Definition Errors on page 330).
An error message reporting a template instantiation error lists the source lines of the error itself and the
source line in which the problematic template instantiation is first created. This report can be
recursivefor example, if the template is instantiated within another template, its own instantiation line
is also referred to, and so on.1
For example, trying to load the following code:
<'
template struct err_struct of (<first'type>, <second'type>) {
x: <first'type>(bits: 32); // => <first'type> must be a scalar type
y: list of <second'type>;
// => <second'type> must not be a list type
};
extend sys {
run() is also {
var x: err_struct of (string, list of int);
};
};
'>

will cause the following two error messages:


*** Error: 'string' is not a scalar type
at line 3 in err.e
x: <first'type>(bits: 32);
from template instantiation 'err_struct of (string,list of int)'
at line 8 in err.e
var x: err_struct of (string, list of int);

*** Error: Cannot define a list of lists


at line 4 in err.e
y: list of <second'type>;
from template instantiation 'err_struct of (string,list of int)'
at line 8 in err.e
var x: err_struct of (string, list of int);

1. If any of the code referencesthe actual erroneous code or one of the template
instantiationsoriginates in a macro, the macro source line is also listed, as for any other macro-related
error messages, as described in Macro Error Messages on page 1118.
Specman e Language Reference
1999-2015

331
.

Product Version 15.1


All Rights Reserved.

If several different template instantiations cause errors on the same line of the template definition, all are
reported, rather than reporting only one error per line.

5.4.3

Run-Time Errors

A run-time error related to a template definition is reported like any other run-time error. Only the actual
error line for interpreted code, or the method containing it for compiled code, is reported, without
reference to the template instantiations. This format applies to all kinds of run-time errors, including
user errors, DUT errors, assertion failures, and so on.

5.5

Template Limitations

The following is a list of known limitations related to templates:

Because template instances are types, you can reference them in interactive commands wherever a
type is allowed. However, a template instance cannot be created interactively. If a specific instance
of a template has not been referenced in the compiled/loaded code, it cannot be used in a command.
Trying to do so causes an error message.
A template instance cannot be created by the reflection mechanism at run-time. If a specific instance
of a template has not been referenced in the compiled/loaded code, the reflection mechanism considers
it to be a nonexistent type.
A template method may not be declared as C routine.
Once a template is defined, it can laterin the same module, or in a later loaded/compiled
modulehave its direct or indirect base type extended. For some instances, however, the members
of the base struct extension might be applied earlier than the members of the original template
definition, although they appear later in the code, so the order of the member is incorrect.
Therefore, the behavior for template instances is undefined, and might be different for different
instances of the same template. A WARN_EXTEND_AFTER_TEMPLATE message is issued
when a template instance is created that has the incorrect order for some of its methods, events, or
expects. If you get this notification, make sure there is no real problem with this order
Note

5.6

This behavior might change in the future, so do not rely on it if the order matters.

Templates Versus Macros

In some sense, templates are similar to define-as macros. Both define parameterized code, which is
instantiated by substituting parameters. In principle, a <statement> macro can be used for that purpose,
if it has <type> syntactic arguments and a struct definition in its replacement code. Calling that macro
creates a specific struct, which is analogous to creating a template instance.
However, there are several important differences that make using templates preferable:
Specman e Language Reference
1999-2015

332

Product Version 15.1


All Rights Reserved.

A macro must be instantiated explicitly in the code. Multiple explicit instantiations of the same macro
cause an error, because the instances are multiple definitions of the same struct. Templates are
instantiated automatically the first time a specific instance is referred to in the code.
A template definition is fully syntactically analyzed, and any syntax errors within a template definition
are reported when the template is defined (see Template Definition Errors on page 330). A macro
definition, in contrast, is not syntactically analyzed, and most syntax errorsexcept basic errors such
as unbalanced parentheses in the codeare discovered only when the macro is called.
With regard to name resolution and related issues, template code is treated in the context of the
template definition, regardless of where a given template instance is referred to for the first time.
Macro code is treated in the context of the macro call itself. For instance, if the macro replacement
code tries to access the package-accessible field of a struct defined in the same package, the macro
call will not compile if it resides in a different package.

To illustrate these differences, assume the following template definition:


template struct stack of <type> {
package items: list of <type>;
pop(): <type> is {
if items.is_empty() { error("Stack is empty") };
return items.pop();
};
push(x: <type>) is {
items.add(x);
};
};

Given this template, when you refer to "stack of int'" and "stack of packet" anywhere in the code, the
corresponding template instance type is created automatically. Furthermore, if you refer to the same
template instance more than once, Specman automatically determines whether the instance already
exists, so it is created only once. For example, the following code creates "stack of int" type once,
although it is used twice in the code:
extend sys {
x: stack of int;
y: stack of packet;
run() is also {
var a: stack of int;
...
};
};

You could implement the same example with a macro, as follows:


define <stack'statement> "stack_decl of <type>" as {
struct stack_<type> {
package items: list of <type>;
pop(): <type> is {
Specman e Language Reference
1999-2015

333
.

Product Version 15.1


All Rights Reserved.

if items.is_empty() { error("Stack is empty") };


return items.pop();
};
push(x: <type>) is {
items.add(x);
};
};
};

However, macros are not automatically instantiated, so if you instantiated this parameterized type with a
certain type as the parameter, you would have to declare it explicitly, as follows:
stack_decl of int;
stack_decl of packet;
extend sys {
x: stack_int;
y: stack_packet;
run() is also {
var a: stack_int;
...
};
};

When you use this macro, the stack_decl statement must appear exactly once for each instance.
Otherwise, a compilation error is reported against any duplicate struct declarations.
Because template code is treated in the context of the template definition, the items field in this example
cannot be accessed outside the package in which the template is declared. For example, if the following
code appears in a different package, it will not compile:
extend sys {
x: stack of int;
run() is also {
print x.items;
};
};

With the template, the items field belongs to the package in which the actual instantiation occurs, so this
code will compile even if it appears in a different package:
stack_decl of int;
extend sys {
x: stack_in;
run() is also {
print x.items;
};
};

Specman e Language Reference


1999-2015

334

Product Version 15.1


All Rights Reserved.

Another drawback of using a macro is that you must invent syntax both for the declaration statement
(stack_decl of xx) and for the type name itself (stack_xxx). The syntax for templates, on the other hand,
is defined by the language.
Finally, if the template declaration has a syntax error, such as a missing semicolon, the error is reported
when you try to compile or load the code containing the declaration. If a macro has a syntax error, it is
not reported until you try to compile or load the code that contains the instantation.

Specman e Language Reference


1999-2015

335
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

336

Product Version 15.1


All Rights Reserved.

e Ports

Simple Port Declarations, References, and Access Operators on page 338

Simple Port MVL Access Methods on page 353

Simple Port Default Value Methods on page 382

Global MVL Conversion Routines on page 386

Simple Indexed Port Declaration and Access Operator on page 398

Event Port Declarations, References, and Access Operator on page 404

API for Controlling Event Port Sensitivity at Run Time on page 412

Method Port Declarations, References, and Access Operator on page 414

Buffer Port Declarations, References, and Access Methods on page 420

e Port Binding Declarations and Methods on page 440

Port-Related Routines on page 470

e TLM Interface Port Declaration and Access Operator on page 474

e TLM Interface Port Binding Declarations and Methods on page 479

e TLM 2.0 Socket Declaration and Predefined Methods on page 486

e TLM 2.0 Predefined Structs and Enumerated Data Types on page 504

e TLM 2.0 Socket Binding Declaration on page 515

See Also

Simulation-Related Methods on page 1272

Specman e Language Reference


1999-2015

337
.

Product Version 15.1


All Rights Reserved.

6.1

Simple Port Declarations, References, and


Access Operators

simple_port on page 338

any_simple_port on page 340

simple_port$ on page 342

simple_port$[ : ] on page 343

force port$ on page 348

force port$[ : ] on page 350

release port on page 352

6.1.1

simple_port

Purpose
Access other port instances or external simulated objects directly

Category
Unit member

Syntax
port-instance-name: [list of] [direction] simple_port of element-type [is instance];
Syntax Examples
data: in simple_port of byte is instance;

Parameters
port-instance-name

A unique identifier you can use to refer to the port or access its value.

direction

One of in, out, or inout. The default is inout, which means that you can read
values from and write values to this port. For an in port, you can only read
values from the port, and for an out port you can only write values to the port.

Specman e Language Reference


1999-2015

338

Product Version 15.1


All Rights Reserved.

element-type

Any predefined or user-defined e type except a port type or a unit type.


Note A multi-dimensional list (list of lists) cannot be used as the element
type for simple or buffer e ports. Lists of lists of ports is supported, but ports of
lists of lists are not supported.

is instance

is instance denotes a physical instance of the port as a hierarchical child of the


instantiating unit. Without is instance, the declaration denotes a variable to be
used as a reference (to an instance defined elsewhere).

Description
You can use simple ports to transfer one data element at a time to or from either an external simulated
object or an internal object (another e unit).
Internal simple ports can transfer data elements of any type. External ports can transfer scalar types
(including MVL data elements), lists of scalar types, and struct types (for SystemC).
The port can be configured to access a different signal by changing the binding; all the code that reads or
writes to the port remains the same. Similarly, port semantics remain the same, regardless of what
simulator is used. Binding is fixed during generation.
A simple ports direction can be either input, output, or inout. The direction specifier in a simple port is
not a when subtype determinant. This means, for example, that the following type:
data: simple_port of byte is instance;

is not the base type of:


data: out simple_port of byte is instance;

Furthermore, the following types are fully equivalent:


data: simple_port of byte is instance;
data: inout simple_port of byte is instance;

Thus, the following constraint is an error because the two types are not equivalent:
data: out simple_port of byte is instance;
!data_ref: simple_port of byte; // means inout simple_port of byte
keep data_ref == data; // error

Example
<'
unit encoder {

Specman e Language Reference


1999-2015

339
.

Product Version 15.1


All Rights Reserved.

data: out simple_port of int(bits:64) is instance;


keep bind(data, external);
keep data.hdl_path() == "data";
drive()@sys.any is {
var v: int(bits:64);
while TRUE {
gen v;
data$ = v;
wait cycle;
wait cycle;
};
};
run() is also {
start drive();
};
};
'>

See Also

Introduction to e Simple Ports in Creating e Testbenches

any_simple_port on page 340

Simple Port Declarations, References, and Access Operators on page 338

Simple Port MVL Access Methods on page 353

Global MVL Conversion Routines on page 386

Simple Port Default Value Methods on page 382

get_hdl_size() on page 470

simulator.get_hdl_path_size() on page 472

6.1.2

any_simple_port

Purpose
Reference a simple port instance

Category
Unit field, variable or method parameter

Specman e Language Reference


1999-2015

340

Product Version 15.1


All Rights Reserved.

Syntax
[! | var] port-reference-name: [direction] simple_port of element-type
[! | var] port-reference-name: any_simple_port
Syntax Example
!last_printed_port: any_simple_port;
!in_int_simple_port_ref: in simple_port of int;

Parameters
port-reference-name

A unique identifier.

direction

One of in, out, or inout

element-type

The data element that can be passed through this port.

Description
Simple port instances may be referenced by a field, a variable, or a method parameter of the same port
type or of the abstract type any_simple_port.
Abstract port types reference only the port kind, not the port direction or data element. Thus, a method
parameter of type any_simple_port accepts all simple ports, including, for example:
data_length: in simple_port of uint is instance;
data: inout simple_port of list of bit is instance;

If a port reference is a field, then it must be marked as non-generated or it must be constrained to an


existing port instance. Otherwise, a generation error results.
Port reference fields can be bound to external | undefined | empty.

Notes

You cannot apply the $ access operator to an item of type any_simple_port. Abstract types do not
have any access methods. For example, the expression port_arg$ == 0 in the following code causes
a syntax error.
check_sig ( port_ref : any_simple_port )@clk is {
if ( port_ref$ == MVL_U) then { -- syntax error
out (sys.time, " Undefined sig");
};
};

Specman e Language Reference


1999-2015

341
.

Product Version 15.1


All Rights Reserved.

You cannot use the any_simple_port abstract type in a port instance.

See Also

Referencing e Ports in Creating e Testbenches

simple_port on page 338

6.1.3

simple_port$

Purpose
Read or write a value to a simple port

Category
Operator

Syntax
port-exp$
Syntax Example
np$ = 0;
mp$ = 32'bz;

// Assigns the value 0 to the simple numeric port 'np'


// Assigns an mvl literal to the simple mvl port 'mp'

Parameters
port-exp

An expression that returns a simple port.

Description
The $ access operator is used to access or update the value held in a simple port. When used on the
right-hand side, p$ refers to the ports value. On the left-hand side of an assignment, p$ refers to the
values location, so an assignment to p$ changes the value held in the port.
Without the $ operator an expression of any type port refers to the port itself, not to its value. In
particular, an expression without the $ operator can be used for operations involving port references.
Note You cannot apply the $ access operator to an item of type any_simple_port. Abstract types do
not have any access methods.
Specman e Language Reference
1999-2015

342

Product Version 15.1


All Rights Reserved.

Example
<'
unit u {
init_port(np: inout simple_port of uint) is {
np$ = 0;
// Assigns the value 0 to the simple numeric port 'np'
};
free_port(mp: inout simple_port of list of mvl) is {
mvlp$ = 32'bz;
// Assigns an mvl literal to the port 'mvlp'
};
};
'>

See Also

Accessing Simple Port Values in Creating e Testbenches

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

Sampling Simulated Objects Before Runtime with External Simple Ports in Creating e Testbenches

Simple Port MVL Access Methods on page 353

6.1.4

simple_port$[ : ]

Purpose
Read or write a value to a bit or a bit slice of a simple port

Category
Operator

Syntax
simple-port-exp$[[high-exp]:[low-exp][: slice]] = rhs-exp
lhs-exp = simple-port-exp$[[high-exp]:[low-exp][: slice]]
Syntax Example
p$[10:3] = 123;
p$[:] = 0x17;

Specman e Language Reference


1999-2015

343
.

Product Version 15.1


All Rights Reserved.

Parameters
simple-port-exp

An expression that returns a simple port instance. The element type has to be scalar,
list of bit or list of byte.

high-exp

A non-negative numeric expression, greater than or equal to the low expression. To


extract a single bit, use the same expression for both the high and the low
expression.

low-exp

A non-negative numeric expression, less than or equal to the high expression.


Default is zero.

slice

One of bit, byte, int, or uint. The default is bit.

rhs-exp

A numeric expression.

lhs-exp

A expression that returns an e variable or field.

Description
The bit slicing operator can be used in a left-hand side (LHS) or right-hand side (RHS) port access
expression. The syntax of the bit slicing expression is described in [ : ] on page 105.
When the expression appears on the left-hand side of an assignment, the specified bits in the location
that the port refers to are set to the value of the RHS expression. The RHS value is chopped or zero/sign
extended, if necessary.
When the expression appears on the right-hand side of an assignment, the specified bits in the location
that the port refers to are written to the LHS expression.

Access to non-existing bits


Any access to non-existing bits of e2e ports causes an error, unless the port is of type unbounded integer.
This is the same behavior of the bit slicing operator.
For external ports, if the element type is list of bit or list of byte, then the list is resized by adding enough
zero bits to make the high expression index valid. On all other port types, any access to non-existing bits
causes an error.
Note

External ports of type infinite integer are not supported.

For external ports, in all cases, the result of the assignment is passed to the adapter, which may modify
the value according to the actual entity accessed on the simulator side. This modification is adapter
dependent. For Cadence adapters, if the passed value is longer than the value holder on the simulator
side, a warning is issued about the loss of information.

Specman e Language Reference


1999-2015

344

Product Version 15.1


All Rights Reserved.

Omitting the high expression index


When the high expression index is not given, if the port is of a bound type (in other words, it is not a port
of type infinite integer or list), then the high expression is taken to be the size of the port expression - 1.
If the port is of unbound type, then

For e2e ports, the size of the port expression is the size of the last assigned value.
For external ports, if there was any assignment during the current tick, it determines the size of the
assigned value. Otherwise, the size of the port expression is the size of the value that the port referred
to, as returned by the adapter.

The effect of an assignment


All the assignments in one Specman tick are executed in the end of the tick. Assignments to different
bits are accumulated. If several assignments were done to the same bit, then the last assignment wins.
That means that if a value is assigned to an input port, then any output port that connected to this port
returns this value only on the next tick.
For example:
<'
unit u {
p1 : out simple_port of int is
p2 : in simple_port of int is
keep bind(p1,p2);
//...
rw()@sys.any is {
p1$ = 0xffffffff;
wait[1];
p1$[7:0] = 0;
print p2$ using hex; -- will
wait[1];
print p2$ using hex; -- will
//...
};
};
'>

instance;
instance;

print 0xffffffff
print 0xffffff00

If the delayed() attribute of the port is set to FALSE, then the effect of the assignment is immediate.
Note The list slicing operator [..] and the list indexing operator [] are not supported for ports in LHS
expressions. In other words, p$[l..h] and p$[i] are not supported on the LHS of an assignment operator.

Specman e Language Reference


1999-2015

345
.

Product Version 15.1


All Rights Reserved.

Example
top.e
<'
unit verifier {
p : inout simple_port of int is instance;
keep bind(p,external);
keep p.hdl_path() == "sig";
clk : in simple_port of bit is instance;
keep bind(clk,external);
keep clk.hdl_path() == "clk";
event clk_rise is rise(clk$)@sim;
run() is also {
start do_the_test();
};
do_the_test()@clk_rise is {
p$ = 0xffffffff;
wait [1];
p.put_mvl_list(32'hxxxxzzzz);
wait [1];
p$[15:12] = 0xa;
check that p.get_mvl_list() == 32'hxxxxzzzz; -- assignments are
-- reflected only in the
-- next tick
p.put_mvl_to_bit_slice(11,8,4'hx);
p$[7:4] = 0xb;
p.put_mvl_to_bit_slice(3,0,4'hx);
wait[1];
force p$ = 0x123;
check that p$ == 0x123;
-- value is reflected immediately
wait[1];
p$ = 100;
-- is ignored
check that p$ == 0x123;
p.put_mvl_list(32'hzzzzzzzz); -- is ignored
check that p$ == 0x123;
wait[1];
p.force_mvl_to_bit_slice(31,24,8'hzx); -- force the most significant
-- byte
wait[1];
release p;
wait[1];
p$ = 0xabcd;
Specman e Language Reference
1999-2015

346

Product Version 15.1


All Rights Reserved.

wait[1];
stop_run();
};
};
extend sys {
v : verifier is instance;
keep v.hdl_path() == "~/top";
};
'>

top.v
module top();
reg
reg[31:0]

clk;
sig;

initial clk <= 0;


always #50 clk <= ~clk;
always @(sig) $display($time, " : sig = %x",sig);
endmodule

Result (with IES-XL)


ncsim> run
50 : sig = ffffffff
150 : sig = xxxxzzzz
250 : sig = xxxxaxbx
350 : sig = 00000123
550 : sig = zx000123
750 : sig = 0000abcd
Last specman tick - stop_run() was called
Normal stop - stop_run() is completed
Checking the test ...
ncsim>

See Also

force port$ on page 348

put_mvl_to_bit_slice() on page 370

force_mvl_to_bit_slice() on page 376

Specman e Language Reference


1999-2015

347
.

Product Version 15.1


All Rights Reserved.

6.1.5

force port$

Purpose
Force a value to a simple port

Category
Action

Syntax
force simple-port-exp$= rhs-exp
Syntax Example
force p1$ = 123;

Parameters
simple-port-exp

An expression that returns a simple port instance.

rhs-exp

An expression of the same type as the ports type.

Description
Forces a value to the simple port. For both e2e and external ports, updates the value held inside the port.
Until the port is released, any other non-force assignment to the port will be ignored. Any subsequent
force assignment overrides the last one.
In addition, for external ports, the result of the force assignment is passed to the adapter.

Effect of force assignment


Force assignments are not delayed. Any forced value is immediately seen by any port that is bound to
the assigned port.

With a Verilog Design


You can apply a force action to any net or wire for which the verilog_wire() and verilog_forcible()
attributes have been set.
Specman e Language Reference
1999-2015

348

Product Version 15.1


All Rights Reserved.

The effect of a force action on a Verilog design is that all preceding and subsequent non-forced
assignments from Specman or from the DUT to the same object including those within the same
Specman tick are ignored until a subsequent force action from e or until freed by a release action
from e. The only exception is that if you force different parts of a vectored object in the same Specman
tick, the actions are accumulated and applied together at the end of the tick.
Note If you use a force action on a port with a verilog_drive() attribute, the force action is ignored.
The drive is performed instead of the force.

With a VHDL Design


You can force signals of a scalar integer or enumerated type as well as binary array type, such as arrays
of std_logic and bit vectors. No declaration is required for VHDL objects.
Note You can force single elements of a VHDL array of a scalar integer or enumerated type using the
predefined routine simulator_command().
The effect of the force action on a VHDL design is:

A release action is required to allow the object to be driven by the DUT.

Each new action from e overrides the previous one without an explicit release action.

To change the behavior of proprietary VHDL adapters to be compatible with this behavior, you can call
the global set_assign_after_force_compatible() method as follows before simulation starts:
Specman > set_assign_after_force_compatible(TRUE)

Setting this method is not required for any of the simulators supported by Specman.

Notes

Forcing signals is always costly to performance.


You can avoid having to enter a force action if you set the port attribute force_always() to TRUE.
For more information, see always_force() in the Specman Integrators Guide.

The force action is not supported for external simple ports with an hdl_expression() attribute.

The force action is not supported for external simple ports with a pli_access() attribute.

The force action is supported for external simple indexed ports for SystemVerilog. See Forcing and
Releasing SystemVerilog Objects Accessed with e Simple Indexed Ports in the Specman Integrators
Guide.
The force action is not supported for external simple ports of struct for SystemC. See Supported
SystemC Objects and Types in the Specman Integrators Guide.

Be careful if your e code contains a scenario similar to the following:


event e is rise (my_port$)@sim;

Specman e Language Reference


1999-2015

349
.

Product Version 15.1


All Rights Reserved.

on e {
some action;
};
run() is also {
force my_port$ =5;
};

The force occurs before the start of simulation. However, even if the force action results in the event
being emitted, the action tied to the event is not performed at time 0, as you might expect.

Example
<'
unit u {
p1 : out simple_port of int is instance;
p2 : in simple_port of int is instance;
keep bind(p1,p2);
//...
rw()@sys.any is {
p1$ = 0xffffffff;
wait[1];
force p1$ = 0xabc;
print p2$ using hex; -- will print 0xabc
//...
};
};
'>

See Also

simple_port$ on page 342

force port$[ : ] on page 350

6.1.6

force port$[ : ]

Purpose
Force a value to a bit or a bit slice of a simple port

Category
Action

Specman e Language Reference


1999-2015

350

Product Version 15.1


All Rights Reserved.

Syntax
force simple-port-exp$[[high-exp]:[low-exp][: slice]] = rhs-exp
Syntax Example
force p1$[10:3] = 123;
force p2$[:] = 0x17;

Parameters
simple-port-exp

An expression that returns a simple port instance. The element type has to be
scalar, list of bit or list of byte.

high-exp

A non-negative numeric expression, greater than or equal to the low expression.


To extract a single bit, use the same expression for both the high and the low
expression.

low-exp

A non-negative numeric expression, less than or equal to the high expression.


Default is zero.

slice

One of bit, byte, int, or uint. The default is bit.

rhs

A numeric expression.

Description
For e2e ports, forcing a slice of a port is the same as forcing the entire port, except that values are written
only to the specified slice. That is, until the next release action, any subsequent non-force assignment is
ignored. Any subsequent force assignment overrides the last one.
For external ports, in addition to the behavior specified for e2e ports, the result of the force assignment
is passed to the adapter.
For more information, see force port$ on page 348.
Note You can avoid having to enter a force action if you set the port attribute force_always() to
TRUE. For more information, see always_force() in the Specman Integrators Guide.

Example
<'
unit u
p1 :
p2 :
keep

{
out simple_port of int is instance;
in simple_port of int is instance;
bind(p1,p2);

Specman e Language Reference


1999-2015

351
.

Product Version 15.1


All Rights Reserved.

//...
rw()@sys.any is {
p1$ = 0xffffffff;
wait[1];
force p1$[7:0] = 0;
print p2$ using hex; -- will print 0xfffff00
//...
};
};
'>

See Also

force port$ on page 348

simple_port$[ : ] on page 343

put_mvl_to_bit_slice() on page 370

force_mvl_to_bit_slice() on page 376

always_force() in the Specman Integrators Guide

6.1.7

release port

Purpose
Remove a force action from a port

Category
Action

Syntax
release simple-port-exp
Syntax Example
release p1;

Parameters
simple-port-exp

An expression that returns a simple port instance.

Specman e Language Reference


1999-2015

352

Product Version 15.1


All Rights Reserved.

Description
Releases a simple port that you previously forced. For e2e ports, the value held in the port is that last
forced value. For external ports, a release request is passed to the adaptor.

See Also

simple_port$[ : ] on page 343

force port$ on page 348

force port$[ : ] on page 350

put_mvl_to_bit_slice() on page 370

force_mvl_to_bit_slice() on page 376

6.2

Simple Port MVL Access Methods

put_mvl() on page 354

get_mvl() on page 355

put_mvl_list() on page 356

fill_mvl_list() on page 357

get_mvl_list() on page 360

put_mvl_string() on page 362

get_mvl_string() on page 363

get_mvl4() on page 364

fill_mvl4_list() on page 366

get_mvl4_list() on page 367

get_mvl4_string() on page 369

put_mvl_to_bit_slice() on page 370

force_mvl() on page 372

force_mvl_list() on page 373

force_mvl_string() on page 375

force_mvl_to_bit_slice() on page 376

has_mvl_value() on page 378

has_mvl_value() on page 378

has_z() on page 380

has_unknown() on page 381

Specman e Language Reference


1999-2015

353
.

Product Version 15.1


All Rights Reserved.

6.2.1

put_mvl()

Purpose
Put an mvl data on a port of a non-mvl type

Category
Predefined method for simple ports

Syntax
simple-port-exp.put_mvl(value: mvl)
Syntax Example
p.put_mvl(MVL_Z)

Parameters
simple-port-exp An expression that returns a simple port instance.
value

A multi-value logic value.

Description
Place an mvl value on an output or inout simple port, to initialize an object to a disconnected value,
for example.
Placing an mvl value on a port whose element type is list places the value in the LSB of the list.

Example
unit uo {
pbo: out simple_port of bit is instance;
keep bind(pbo, external);
disconnect_pbo() is {
pbo.put_mvl(MVL_Z);
};
};

Specman e Language Reference


1999-2015

354

Product Version 15.1


All Rights Reserved.

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

6.2.2

get_mvl()

Purpose
Read mvl data from a port of a non-mvl type

Category
Predefined method for simple ports

Syntax
simple-port-exp.get_mvl(): mvl
Syntax Example
check that pbi.get_mvl() != MVL_X else dut_error("Bad value");

Parameters
simple-port-exp

An expression that returns a simple port instance.

Description
Reads an mvl value from an input or inout simple port, to check that there are no undefined x bits, for
example.
Getting an mvl value from a port whose element type is list reads the LSB of the list.

Example
unit ui {
pbi: in simple_port of bit is instance;
keep bind(pbi, external);
chk_pbi() is {
check that pbi.get_mvl() != MVL_X else
dut_error("Bad value");
Specman e Language Reference
1999-2015

355
.

Product Version 15.1


All Rights Reserved.

};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

6.2.3

put_mvl_list()

Purpose
Put a list of mvl values on a port of a non-mvl type

Category
Predefined method for simple ports

Syntax
simple-port-exp.put_mvl_list(values: list of mvl)
Syntax Example
pbo.put_mvl_list({MVL_H; MVL_0; MVL_L; MVL_0});
pbo.put_mvl_list({4'bz});

Parameters
simple-port-exp

An expression that returns a simple port instance.

values

A list of mvl values

Description
Writes a list of mvl values to an output or inout simple port. You can write the value as a list, for
example:
{MVL_X;MVL_X;MVL_X;MVL_X}

Specman e Language Reference


1999-2015

356

Product Version 15.1


All Rights Reserved.

Alternatively, you can write the value as an MVL literal. An MVL literal, which is a literal of type list of
mvl, provides a more convenient syntax for assigning MVL values. The syntax of an MVL literal is as
follows:
<width-number>'(b|o|h)<value-number>

The width number is an unsigned decimal integer specifying the size of the list. The value number is any
sequence of digits that are legal for the base, plus x, z, u, l, h, w, n.
Putting a list of mvl values on a port whose element type is a single bit writes only the LSB of the list.

Example
unit ui {
pbi: in simple_port of uint(bits:4) is instance;
};
unit uo {
uin: ui is instance;
pbo: out simple_port of uint(bits:4) is instance;
keep bind(pbo, uin.pbi);
wr_pbo() is {
pbo.put_mvl_list({MVL_H; MVL_0; MVL_L; MVL_0});
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

6.2.4

fill_mvl_list()

Purpose
Get a list of MVL values from a port of a non-MVL type. Similar to get_mvl_list(), except that it uses
an existing buffer list instead of creating new list.

Category
Predefined method for simple ports

Specman e Language Reference


1999-2015

357
.

Product Version 15.1


All Rights Reserved.

Syntax
simple-port-exp.fill_mvl_list(mvl-list: list of mvl)
Syntax Example
check that p.fill_mvl_list(buffer).has(it == MVL_U) == FALSE else
dut_error("Bad list");

Parameters
simple-port-exp

An expression that returns a simple port instance.

mvl-list

A list of MVL.
You need to keep the mvl-list as a field or TCM variable for reuse. If you keep this
list elsewhere, it might produce unexpected results when the buffer is used again.

Description
Reads a list of MVL values from an input or inout simple non-MVL port and puts the values into the
mvl-list.
fill_mvl_list() allows more aggressive dynamic memory optimization of your e code than
get_mvl_list(). The optimization might be especially significant when MVL checks are done for many
signals per clock.
For a simple analysis of MVL values of a port, you might be able to use has_mvl_value() on page 378,
has_x() on page 379, has_z() on page 380, or has_unknown() on page 381. If these predefined
methods serve your purpose, they are should be preferred to using fill_mvl_list() or get_mvl_list().

Note
For external ports of a fixed scalar type, the fill_mvl_list() method currently sets the mvl-list to the same
size as the HDL signal to which the port is bound. You can change this behavior to to set the MVL list to
the same size as the scalar element type of the port. You can turn on the new behavior by setting config
simulation -resize_mvl_list to TRUE.
With the new behavior:

If the size of the MVL list from the HDL signal is larger than the size of the element type of the port,
the MVL list is shortened to the size of the element type of the port.

Specman e Language Reference


1999-2015

358

Product Version 15.1


All Rights Reserved.

If the size of the MVL list from the HDL signal is smaller than the size of the element type of the
port, the MVL list is enlarged to the size of the element type of the port, and the new positions are
filled with the fill value MVL_U.

A mismatch between the size of the mvl-list after calling fill_mvl_list() when -resize_mvl_list is set to
TRUE and the size of the scalar element type of the port (which is the size of the mvl-list after calling
fill_mvl_list() when -resize_mvl_list is set to FALSE) triggers the DEPR_RESIZE_MVL_LIST
notification. By default, this notification is set to IGNORE, which means you will not see the
notification message. If you want to see the notification message, set DEPR_RESIZE_MVL_LIST to
WARNING.
Note that the new behavior applies only for external simple ports of a fixed scalar type. For external
simple ports of other types, for example type list of int, fill_mvl_list() continues to get a list that is the
same size as the HDL signal, under both the old behavior and the new behavior.

Example 1
checker()@clk is {
var mvll: list of MVL;
while TRUE {
p.fill_mvl_list(mvll);
for each in mvll {
case it {
[MVL_X,MVL_Z: { notify_unknown(index) }
[MVL_W,MVL_H,MVL_N]: { notify_weak(index) }
};
};
wait;
};
};

Example 2
As described above, you need to keep the mvl-list as a field or TCM variable for reuse. If you keep this
list elsewhere, it might produce unexpected results when the buffer is used again.
In the following example, you cannot guarantee that the mvl_buffer list will be unchanged by the
mvl_check() method. Furthermore, after the delay, the mvl_buffer values could be changed by any other
TCM.
mvl_buffer : list of mlv;
...
checker@clk is {
p0.fill_mvl_list(mvl_buffer);
start mvl_check(mvl_buffer);
wait delay(20);
p1.put_mvl_list(mvl_buffer);
Specman e Language Reference
1999-2015

359
.

Product Version 15.1


All Rights Reserved.

};
mvl_check(mvll: list of mvl)@sys.any is {
for each in mvll {
do_the_check(it, index);
};
};

To solve this issue, the following example ensures that the mvl_buffer list is initalized and manipulated
at time zero:
mvl_buffer : list of mlv;
...
checker@clk is {
p0.fill_mvl_list(mvl_buffer);
for each in mvl_buffer {
do_the_check(it, index);
};
p1.put_mvl_list(mvl_buffer);
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

get_mvl_list() on page 360

MVL Literals and the mvl Type on page 37

configure simulation in the Specman Command Reference

6.2.5

get_mvl_list()

Purpose
Get a list of mvl values from a port of a non-mvl type

Category
Predefined method for simple ports

Syntax
simple-port-exp.get_mvl_list(): list of mvl

Specman e Language Reference


1999-2015

360

Product Version 15.1


All Rights Reserved.

Syntax Example
check that pbil.get_mvl_list().has(it == MVL_U) == FALSE else
dut_error("Bad list");

Parameters
simple-port-exp

An expression that returns a simple port instance.

Description
Reads a list of mvl values from an input or inout simple port.

Note
For external ports of a fixed scalar type, the get_mvl_list() method currently gets a list that is the same
size as the HDL signal to which the port is bound. You can change this behavior to get a list that is the
same size as the scalar element type of the port. You can turn on the new behavior by setting config
simulation -resize_mvl_list to TRUE.
With the new behavior:

If the size of the MVL list from the HDL signal is larger than the size of the element type of the port,
The MVL list is shortened to the size of the element type of the port.
If the size of the MVL list from the HDL signal is smaller than the size of the element type of the
port, The MVL list is enlarged to the size of the element type of the port, and the new positions are
filled with the fill value MVL_U.

A mismatch between the size of the list returned from get_mvl_list() when -resize_mvl_list is set to
TRUE and the size of the scalar element type of the port returned from get_mvl_list() when
-resize_mvl_list is set to FALSE triggers the DEPR_RESIZE_MVL_LIST notification. By default, this
notification is set to IGNORE, which means you will not see the notification message. If you want to see
the notification message, set DEPR_RESIZE_MVL_LIST to WARNING.
Note that the new behavior applies only for external simple ports of a fixed scalar type. For external
simple ports of other types, for example type list of int, get_mvl_list() continues to get a list that is the
same size as the HDL signal, under both the old behavior and the new behavior.

Example
unit uo {
pbol: out simple_port of list of bit is instance;
};

Specman e Language Reference


1999-2015

361
.

Product Version 15.1


All Rights Reserved.

unit ui {
uout: uo is instance;
pbil: in simple_port of list of bit is instance;
keep bind(uout.pbol, pbil);
chk_pbil() is {
check that pbil.get_mvl_list().has(it == MVL_U) == FALSE else
dut_error("Bad list");
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

configure simulation in the Specman Command Reference

6.2.6

put_mvl_string()

Purpose
Put an mvl value on a port of a non-mvl type when a value is represented as a string

Category
Predefined method for simple ports

Syntax
simple-port-exp.put_mvl_string(value: string)
Syntax Example
pbol.put_mvl_string("32'hxxxx1111");

Parameters
simple-port-exp

An expression that returns a simple port instance.

Specman e Language Reference


1999-2015

362

Product Version 15.1


All Rights Reserved.

value

An mvl value in the form of a base and one or more characters,


entered as a string. The mvl values in the string must be lowercase.
Use 1 for MVL_1, 0 for MVL_0, z for MVL_Z, and so on.

Description
Writes a string representing a list of mvl values to a simple output or inout port. The mvl value consists
of any legal Specman base, for example, 32'b, followed by one or more characters, for example
xxxxzzzz. The string representation follows the same rules as Verilog literals. The difference is that
Verilog literals support only 4-value logic digits (1,0,x and z) while Specman allows also the characters
u, l, h, w and n.

Example
unit uo {
pbol: out simple_port of uint(bits:4) is instance;
keep bind(pbol, external);
wr_pbol() is {
pbol.put_mvl_string("32'hxxxx1111");
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

6.2.7

get_mvl_string()

Purpose
Get a value in form of a string from a port of a non-mvl type

Category
Predefined method for simple ports

Syntax
simple-port-exp.get_mvl_string(radix: radix): string
Specman e Language Reference
1999-2015

363
.

Product Version 15.1


All Rights Reserved.

Syntax Example
print pbis.get_mvl_string(BIN);

Parameters
simple-port-exp

An expression that returns a simple port instance.

radix

One of BIN, OCT, or HEX.

Description
Returns a string in which each character represents an mvl value. The characters are lowercase. HDL
value 1 is represented by the character 1, Z by z, - by character n. The returned string always
includes all the bits, with no implicit extensions. For example, a port of type uint returns a string of 32
characters, since an int is a 32-bit data type.

Example
unit ui {
pbis: in simple_port of uint(bits:4) is instance;
keep bind(pbis,external);
chk_pbis() is {
print pbis.get_mvl_string(BIN);
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

6.2.8

get_mvl4()

Purpose
Get an mvl value from a port, converting 9-value logic to 4-value logic

Specman e Language Reference


1999-2015

364

Product Version 15.1


All Rights Reserved.

Category
Predefined method for simple ports

Syntax
simple-port-exp.get_mvl4(): mvl
Syntax Example
check that pbi.get_mvl4() != MVL_Z else dut_error("Bad value");

Parameters
simple-port-exp

An expression that returns a simple port instance.

Description
Reads a 9-value mvl value from an input simple port and converts it to 4-value subset mvl.
The predefined mapping from 9-value logic to 4-value logic is:
MVL_U, MVL_W, MVL_X, MVL_N -> MVL_X
MVL_L, MVL_0 -> 0
MVL_H, MVL_1 -> 1
MVL_Z -> MVL_Z

Example
unit ui {
pbi: in simple_port of bit is instance;
keep bind(pbi, external);
chk_pbi() is {
check that pbi.get_mvl4() != MVL_X else
dut_error("Bad value");
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

Specman e Language Reference


1999-2015

365
.

Product Version 15.1


All Rights Reserved.

6.2.9

fill_mvl4_list()

Purpose
Get a list of MVL values from a port, converting it from 9-value logic to 4-value logic. Similar to
get_mvl4_list(), except that it uses an existing buffer list instead of creating new list.

Category
Predefined method for simple ports

Syntax
simple-port-exp.fill_mvl4_list(mvl-list: list of mvl)
Syntax Example
port.fill_mvl4_list(buffer);

Parameters
simple-port-exp

An expression that returns a simple port instance.

mvl-list

A list of MVL values.


You need to keep the mvl-list as a field or TCM variable for reuse. If you keep this list
elsewhere, it might produce unexpected results when the buffer is used again.

Description
Reads a list of 9-value MVL values from an input simple port and converts them to 4-value logic.
fill_mvl4_list() allows more aggressive dynamic memory optimization of your e code than
get_mvl4_list().
The predefined mapping from 9-value logic to 4-value logic is:
MVL_U, MVL_W, MVL_X, MVL_N -> MVL_X
MVL_L, MVL_0 -> 0
MVL_H, MVL_1 -> 1
MVL_Z -> MVL_Z

Example
Example Using get_mvl4_list():
Specman e Language Reference
1999-2015

366

Product Version 15.1


All Rights Reserved.

checker()@clk is
while TRUE {
var mvll
for each
case

{
:= p.get_mvl4_list();
in mvll {
it {
[MVL_X,MVL_Z]: { notify_unknown(index) }
0: { notify_false(index) }
1: { notify_true(index) }

};
};
wait;
};
};

Optimized Example Using fill_mvl4_list():


checker()@clk is {
var mvll: list of mvl;
while TRUE {
p.fill_mvl_list(mvll);
for each in mvll {
case it {
[MVL_X,MVL_Z]: { notify_unknown(index)}
0: { notify_false(index) }
1: { notify_true(index) } };
};
wait;
};
};

See Also

For more information and additional examples, see fill_mvl_list() on page 357

get_mvl4_list() on page 367

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

6.2.10

get_mvl4_list()

Purpose
Get a list of mvl values from a port, converting from 9-value logic to 4-value logic

Specman e Language Reference


1999-2015

367
.

Product Version 15.1


All Rights Reserved.

Category
Predefined method for simple ports

Syntax
simple-port-exp.get_mvl4_list(): list of mvl
Syntax Example
check that pbi4l.get_mvl4_list().has(it == MVL_X) == FALSE else
dut_error("Bad list");

Parameters
simple-port-exp

An expression that returns a simple port instance.

Description
Reads a list of 9-value mvl values from an input simple port and converts them to 4-value MVL.
The predefined mapping from 9-value logic to 4-value logic is:
MVL_U, MVL_W, MVL_X, MVL_N -> MVL_X
MVL_L, MVL_0 -> 0
MVL_H, MVL_1 -> 1
MVL_Z -> MVL_Z

Example
unit ui {
pbi4l: in simple_port of list of bit is instance;
keep bind(pbi4l, external);
chk_pbi4l() is {
check that pbi4l.get_mvl4_list().has(it == MVL_X) == FALSE else
dut_error("Bad list");
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

Specman e Language Reference


1999-2015

368

Product Version 15.1


All Rights Reserved.

6.2.11

get_mvl4_string()

Purpose
Get a 4-state value in form of a string from a port of a non-mvl type

Category
Predefined method for simple ports

Syntax
simple-port-exp.get_mvl4_string(radix): string
Syntax Example
print pbi4s.get_mvl4_string(BIN);

Parameters
simple-port-exp

An expression that returns a simple port instance.

radix

One of BIN, OCT, or HEX.

Description
Reads a string in which each character represents a 4-value logic digit from a subset of mvl, converted
from 9-value logic. The characters are lowercase.
The predefined mapping from 9-value logic to 4-value logic is the same as it is commonly used when
converting from VHDL std_logic to Verilog:
U, W, X, N -> x
L, 0 -> 0
H, 1 -> 1
Z -> z

The returned string always includes all the bits, with no implicit extensions. For example, a port of type
int returns a string of 32 characters, since an int is a 32-bit data type.

Example
unit ui {
Specman e Language Reference
1999-2015

369
.

Product Version 15.1


All Rights Reserved.

pbi4s: in simple_port of list of int(bits:4) is instance;


keep bind(pbi4s,external);
chk_pbi4s() is {
print pbi4s.get_mvl4_string(HEX);
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

MVL Literals and the mvl Type on page 37

6.2.12

put_mvl_to_bit_slice()

Purpose
Write mvl data to a bit slice of a port

Category
Predefined method for simple out and inout ports

Syntax
simple-port-exp.put_mvl_to_bit_slice(high: int, low: int, value: list of mvl)
Syntax Example
p1.put_mvl_to_bit_slice(7, 4, 4'hx);
p2.put_mvl_to_bit_slice(12, 7, {MVL_X;MVL_X;MVL_H;MVL_H;MVL_U});

Parameters
simple-port-exp

An expression that returns a simple out or inout port instance. The supported element
types are scalar, list of bit or list of byte.

high

An integer that specifies the high index of the bit slice.

low

An integer that specifies the low index of the bit slice.

value

A list of mvl.

Specman e Language Reference


1999-2015

370

Product Version 15.1


All Rights Reserved.

Description
Writes an mvl list to a specified slice of bit. Like the LHS bit slice operator, you can call this method port
of type scalar, list of bit or list of byte.
If the size of the value is smaller than the slice size (1 + high - low), the value is padded with MVL_Us.
If the size of the value is larger than the slice size, then the MSBs of value are truncated.

Access to non-existing bits


For e2e ports, any access to non-existing bits causes an error, unless the port is of type unbounded
integer.
For external ports, if the port type is list of bit or list of byte, then the port's mvl list is resized by adding
enough MVL_U-s, to make the high index valid. On all other port types, the behavior is as on e2e ports.
Note

External ports of type infinite integer are not supported.

In all cases, the result of the assignment is passed to the adapter, which may modify it according to the
entity on the simulator side. This modification is adapter dependent. For Cadence adapters, if the passed
value is longer than the value holder on the simulator side, a warning is issued regarding the loss of
information.

Effect of the function call


Like the bit slice operator, the effect of the assignment is delayed to the next tick. Thus, if the function
put_mvl_to_bit_slice() is called for a port, the consequence of this call is not seen until the next tick by
any other port that is bound to it.
For example:
unit u{
p1: out simple_port of int is instance;
p2: in simple_port of int is instance;
keep bind(p1,p2);
rw() @sys.any is {
p1.put_mvl_list(32'hzzzzzzzz);
wait[1];
p1.put_mvl_to_bit_slice(7,0,8'hxx);
print p2.get_mvl_string(HEX); --will print "32'hzzzzzzzz"
wait[1];
print p2.get_mvl_string(HEX); --will print "32'hzzzzzzxx"
};
};

Specman e Language Reference


1999-2015

371
.

Product Version 15.1


All Rights Reserved.

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

simple_port$[ : ] on page 343

force port$[ : ] on page 350

force_mvl_to_bit_slice() on page 376

MVL Literals and the mvl Type on page 37

6.2.13

force_mvl()

Purpose
Force mvl data on a port of a non-mvl type

Category
Predefined method for simple ports

Syntax
simple-port-exp.force_mvl(value: MVL value)
Syntax Example
p.force_mvl(MVL_Z);

Parameters
simple-port-exp

An expression that returns a simple port instance.

value

An MVLvalue.

Description
Forces an mvl value to the specified simple port. For both e2e and external ports, updates the value held
inside the port.
Until the port is released, any other non-force assignment to the port is ignored. Any subsequent force
assignment overrides the last one.
For external ports, the result of the force assignment is passed to the adapter.
Specman e Language Reference
1999-2015

372

Product Version 15.1


All Rights Reserved.

Effect of the force assignment


Force assignments are not delayed. Any forced value is immediately seen by any port that is bound to
the assigned port.

Example
unit u {
pbo : out simple_port of bit is instance;
keep bind(pbo, external);
force_disconnect_pbo() is {
pbo.force_mvl(MVL_Z);
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

simple_port$[ : ] on page 343

force port$[ : ] on page 350

MVL Literals and the mvl Type on page 37

6.2.14

force_mvl_list()

Purpose
Force a list of mvl values on a port of a non-mvl type

Category
Predefined method for simple ports

Syntax
exp.force_mvl_list(values: list of mvl)
Syntax Example
pbo.force_mvl_list({MVL_H; MVL_0; MVL_L; MVL_0});
pbo.force_mvl_list(4'bz);

Specman e Language Reference


1999-2015

373
.

Product Version 15.1


All Rights Reserved.

Parameters
simple-port-exp

An expression that returns an output or inout simple port instance.

values

A list of mvl.

Description
Forces a list of mvl values to the specified output or inout simple port. For both e2e and external ports,
updates the value held inside the port.
Until the port is released, any other non-force assignment to the port is ignored. Any subsequent force
assignment overrides the last one.
For external ports, the result of the force assignment is passed to the adapter.

Effect of the force assignment


Force assignments are not delayed. Any forced value is immediately seen by any port that is bound to
the assigned port.

Example
unit ui {
pbi : in simple_port of uint(bits:4) is instance;
};
unit uo {
uin: ui is instance;
pbo: out simple_port of uint(bits:4) is instance;
keep bind(pbo, uin.pbi);
wr_pbo() is {
pbo.force_mvl_list({MVL_H; MVL_0; MVL_L; MVL_0});
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

simple_port$[ : ] on page 343

force port$[ : ] on page 350

MVL Literals and the mvl Type on page 37

Specman e Language Reference


1999-2015

374

Product Version 15.1


All Rights Reserved.

6.2.15

force_mvl_string()

Purpose
Force an mvl value on a port of a non-mvl type when the value is represented as a string

Category
Predefined method for simple ports

Syntax
simple-port-exp.force_mvl_string(value: string)
Syntax Example
pbo.force_mvl_string("32'hxxxx1111");

Parameters
simple-port-exp

An expression that returns an output or inout simple port instance.

value

An mvl value represented as a string.

Description
Forces a string representing a list of mvl values to the specified output or inout simple port. For both e2e
and external ports, updates the value held inside the port.
Until the port is released, any other non-force assignment to the port is ignored. Any subsequent force
assignment overrides the last one.
For external ports, the result of the force assignment is passed to the adapter.

Effect of the force assignment


Force assignments are not delayed. Any forced value is immediately seen by any port that is bound to
the assigned port.

Example
unit uo {
Specman e Language Reference
1999-2015

375
.

Product Version 15.1


All Rights Reserved.

pbol: out simple_port of uint(bits:4) is instance;


keep bind(pbol, external);
force_pbol() is {
pbol.force_mvl_string("32'hxxxx1111");
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

simple_port$[ : ] on page 343

force port$[ : ] on page 350

MVL Literals and the mvl Type on page 37

6.2.16

force_mvl_to_bit_slice()

Purpose
Force mvl data to a bit slice of a port

Category
Predefined method for simple out and inout ports

Syntax
simple-port-exp.force_mvl_to_bit_slice(high: int, low: int, value: list of mvl,)
Syntax Example
p1.force_mvl_to_bit_slice(7, 4, 4'hx);
p2.force_mvl_to_bit_slice(12, 7, {MVL_X;MVL_X;MVL_H;MVL_H;MVL_U});

Parameters
simple-port-exp

An expression that returns a simple out or inout port instance. The supported element
types are scalar, list of bit or list of byte.

high

An integer that specifies the high index of the bit slice.

Specman e Language Reference


1999-2015

376

Product Version 15.1


All Rights Reserved.

low

An integer that specifies the low index of the bit slice.

value

A list of mvl.

Description
For e2e ports, forcing a slice of a port is the same as forcing the entire port, except that values are written
only to the specified slice. That is, until the next release action, any subsequent non-force assignment is
ignored. Any subsequent force assignment overrides the last one.
For external ports, in addition to the behavior specified for e2e ports, the result of the force assignment
is passed to the adapter.

Effect of the function call


Force assignments are not delayed. The effect of the function call is immediately seen by any port that is
bound to the assigned port.

Example
unit u {
p1 : out simple_port of int is instance;
p2 : in simple_port of int is instance;
keep bind(p1,p2);
//...
rw()@sys.any is {
p1.put_mvl_list(32'hzzzzzzzz);
wait[1];
p1.force_mvl_to_bit_slice(7,0,8'xx);
print p2.get_mvl_string(HEX); --will print "32'hzzzzzzxx"
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

simple_port$[ : ] on page 343

force port$[ : ] on page 350

put_mvl_to_bit_slice() on page 370

MVL Literals and the mvl Type on page 37

Specman e Language Reference


1999-2015

377
.

Product Version 15.1


All Rights Reserved.

6.2.17

has_mvl_value()

Purpose
Determine if port has a given MVL value

Category
Predefined method for simple ports

Syntax
simple-port-exp.has_mvl_value(value:mvl) : bool
Syntax Example
print pbi4s.has_mvl_value(MVL_Z);

Parameters
simple-port-exp

An expression of a simple port type.

value

A legal MVL value.

Description
Returns TRUE if at least one bit of the port equals the given value.

Example
unit ui {
pbi4s: in simple_port of uint(bits:4) is instance;
keep bind(pbi4s,external);
chk_pbi4s() is {
print pbi4s.has_mvl_value(MVL_X);
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

Specman e Language Reference


1999-2015

378

Product Version 15.1


All Rights Reserved.

has_x() on page 379

has_z() on page 380

has_unknown() on page 381

MVL Literals and the mvl Type on page 37

6.2.18

has_x()

Purpose
Determine if port has X

Category
Predefined method for simple ports

Syntax
simple-port-exp.has_x(): bool
Syntax Example
print pbi4s.has_x();

Parameters
simple-port-exp

An expression of a simple port type.

Description
Returns TRUE if at least one bit of the port is MVL_X.

Example
unit ui {
pbi4s: in simple_port of uint(bits:4) is instance;
keep bind(pbi4s,external);
chk_pbi4s() is {
print pbi4s.has_x();
};
};

Specman e Language Reference


1999-2015

379
.

Product Version 15.1


All Rights Reserved.

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

has_mvl_value() on page 378

has_z() on page 380

has_unknown() on page 381

MVL Literals and the mvl Type on page 37

6.2.19

has_z()

Purpose
Determine if port has Z

Category
Predefined method for simple ports

Syntax
simple-port-exp.has_z(): bool
Syntax Example
print pbi4s.has_z();

Parameters
simple-port-exp

An expression of a simple port type.

Description
Returns TRUE if at least one bit of the port is MVL_Z.

Example
unit ui {
pbi4s: in simple_port of uint(bits:4) is instance;
Specman e Language Reference
1999-2015

380

Product Version 15.1


All Rights Reserved.

keep bind(pbi4s,external);
chk_pbi4s() is {
print pbi4s.has_z();
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

has_mvl_value() on page 378

has_mvl_value() on page 378

has_unknown() on page 381

MVL Literals and the mvl Type on page 37

6.2.20

has_unknown()

Purpose
Determine if port has U

Category
Predefined method for simple ports

Syntax
simple-port-exp.has_unknown(): bool
Syntax Example
print pbi4s.has_unknown();

Parameters
simple-port-exp An expression of a simple port type.

Description
Returns TRUE if at least one bit of the port is one of the following:
Specman e Language Reference
1999-2015

381
.

Product Version 15.1


All Rights Reserved.

MVL_U
MVL_X
MVL_Z
MVL_W
MVL_N

Example
unit ui {
pbi4s: in simple_port of uint(bits:4) is instance;
keep bind(pbi4s,external);
chk_pbi4s() is {
print pbi4s.has_unknown();
};
};

See Also

Accessing Multi-Value Logic (MVL) on Simple Ports in Creating e Testbenches

has_mvl_value() on page 378

has_mvl_value() on page 378

has_z() on page 380

MVL Literals and the mvl Type on page 37

6.3

Simple Port Default Value Methods

set_default_value() on page 382

set_default_mvl_value() on page 384

6.3.1

set_default_value()

Purpose
Set the default value for a simple port or a bound set of simple ports

Category
Pseudo-method

Specman e Language Reference


1999-2015

382

Product Version 15.1


All Rights Reserved.

Syntax
port-exp.set_default_value(value: port-element-type);
Syntax Example
p1.set_default_value(15);

Parameters
port-exp

An expression of a simple port type.

value

An expression of the same type as the port element.

Description
Sets the default value of a simple port or a bound set of simple ports. The default value is stored as the
value of the port or ports during the connect_ports() phase before simulation begins. If this value is not
specified, then the default value is the same as the default value of the element type (usually 0 or
NULL).
The default value applies if an input port is read before it is written. The typical use of these methods is
to set the value read from a port with an empty binding.
As with port assignments, the default value can be either a non-MVL or an MVL value. To set a
non-MVL value, use set_default_value(). To set an MVL value, use set_default_mvl_value(). A port
holds only one default value, so these functions override each other.
When set_default_value() is applied to a port in a bound set, the default value is applied to the entire
bound set.
If set_default_value() is applied to a bound set several times, then each new operation overrides the
previous ones.
When two ports that belong to different bound sets are bound to form a new bound set:

If both ports have default values defined and those values are different, the default value of the new
bound set is considered invalid. The default value must be set again or an elaboration time error occurs
If both ports have the same default value, it becomes the default value of the newly bound set.
Note In the above two cases, if one default value was set using set_default_mvl_value(), and
another one was set using set_default_value(), the default values are always considered different.
The default value has to be set again after the binding to avoid elaboration time error.

If only one port has a default value, then this becomes the default value of the new bound set.

Specman e Language Reference


1999-2015

383
.

Product Version 15.1


All Rights Reserved.

If no port has a default value, then the new bound set has no default value.

Notes

set_default_value() can be called only during the connect_ports() sub-phase.


If a bound set contains an input port with an external binding, the value is always read from the
simulator and the default value never applies.

Example
unit my_unit {
p1 : in simple_port of int is instance;
keep bind(p1,empty);
connect_ports() is also {
p1.set_default_value(15);
};
verify()@sys.any is {
print p1$; // prints 15;
assert p1.get_mvl_list() == 32h0000000F
};
};

See Also

Setting Default Values for Empty Simple Ports in Creating e Testbenches

set_default_mvl_value() on page 384

6.3.2

set_default_mvl_value()

Purpose
Set the default value for a simple port or a bound set of simple ports

Category
Pseudo-method

Syntax
port-exp.set_default_mvl_value(mvl-list: list of mvl);

Specman e Language Reference


1999-2015

384

Product Version 15.1


All Rights Reserved.

Syntax Example
p1.set_default_mvl_value(32'huuuuxxzz);

Parameters
port-exp

An expression of a simple port type.

mvl-list

An expression of type list of mvl.

Description
Sets the default value of a simple port or a bound set of simple ports. The default value is stored as the
value of the port or ports during the connect_ports() phase before simulation begins. If this value is not
specified, then the default value is the same as the default value of the element type (usually 0 or
NULL).
The default value applies if an input port is read before it is written. The typical use of these methods is
to set the value read from a port with an empty binding.
As with port assignments, the default value can be either a non-MVL or an MVL value. To set a
non-MVL value, use set_default_value(). To set an MVL value, use set_default_mvl_value(). A port
holds only one default value, so these functions override each other.
When set_default_mvl_value() is applied to a port in a bound set, the default value is applied to the
entire bound set.
If set_default_mvl_value() is applied to a bound set several times, then each new operation overrides
the previous ones.
When two ports that belong to different bound sets are bound to form a new bound set:

If both ports have default values defined and those values are different, the default value of the new
bound set is considered invalid. The default value must be set again or an elaboration time error occurs
If both ports have the same default value, it becomes the default value of the newly bound set.
Note In the above two cases, if one default value was set using set_default_mvl_value(), and
another one was set using set_default_value(), the default values are always considered different.
The default value has to be set again after the binding to avoid elaboration time error.

If only one port has a default value, then this becomes the default value of the new bound set.

If no port has a default value, then the new bound set has no default value.

Specman e Language Reference


1999-2015

385
.

Product Version 15.1


All Rights Reserved.

Note

set_default_mvl_value() can be called only during the connect_ports() sub-phase.


If a bound set contains an input port with an external binding, the value is always read from the
simulator and the default value never applies.

Example 1
unit my_unit {
p1 : in simple_port of int is instance;
keep bind(p1,empty);
connect_ports() is also {
p1.set_default_mvl_value(32'huuuuxxzz);
};
verify()@sys.any is {
print p1$; // will print 255
assert p1.get_mvl_list() == 32'huuuuxxzz;
};
};

See Also

Setting Default Values for Empty Simple Ports in Creating e Testbenches

set_default_mvl_value() on page 384

6.4

Global MVL Conversion Routines

string_to_mvl() on page 387

mvl_to_string() on page 388

mvl_to_int() on page 389

int_to_mvl() on page 390

mvl_to_bits() on page 391

bits_to_mvl() on page 392

mvl_to_mvl4() on page 393

convert_mvl_list_to_mvl4_list() on page 395

mvl_list_to_mvl4_list() on page 396

string_to_mvl4() on page 397

Specman e Language Reference


1999-2015

386

Product Version 15.1


All Rights Reserved.

6.4.1

string_to_mvl()

Purpose
Convert a string to a list of mvl values

Category
Predefined routine

Syntax
string_to_mvl(value-string: string): list of mvl
Syntax Example
mlist = string_to_mvl("8'bxz1");

Parameters
value-string

A string representing mvl values, consisting of a width and base followed by a series
of characters corresponding to mvl values. Format of the input string is the same as in
Verilog literals, except there are additional 9-value logic digits: u, l, h, w and n.

Description
Converts each character in the input string to an mvl value.

Example
var mlist: list of mvl;
mlist = string_to_mvl("8'bz");
// returns {MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_Z};
mlist = string_to_mvl("8'bxz1");
// returns {MVL_1; MVL_Z; MVL_X; MVL_X; MVL_X; MVL_X; MVL_X; MVL_X};

See Also

mvl_to_string() on page 388

Specman e Language Reference


1999-2015

387
.

Product Version 15.1


All Rights Reserved.

6.4.2

mvl_to_string()

Purpose
Convert a list of mvl values to a string

Category
Predefined routine

Syntax
mvl_to_string(mvl-list: list of mvl, radix: radix): string
Syntax Example
mstring = mvl_to_string({MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_X; MVL_X; MVL_X;
MVL_X}, BIN);

Parameters
mvl-list

A list of mvl values.

radix

One of BIN, OCT, or HEX.

Description
Converts a list of mvl values to a string. The mapping is done in the following way:
MVL_U
MVL_X
MVL_0
MVL_1
MVL_Z
MVL_W
MVL_L
MVL_H
MVL_N

Note

is converted to character "u" (lowercase)


- "x"
- "0"
- "1"
- "z"
- "w";
- "l"
- "h"
- "n"

This routine always returns a sized number as a string.

Example 1
var mstring: string;
Specman e Language Reference
1999-2015

388

Product Version 15.1


All Rights Reserved.

mstring = mvl_to_string({MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_X; MVL_X; MVL_X;


MVL_X}, BIN);
// returns "8b'zzzzxxxx"

Example 2
var l: list of mvl = {MVL_1;MVL_0};
print mvl_to_string(l, BIN); --prints 2'b10
print mvl_to_string(l, HEX); --prints 2'h2

See Also

string_to_mvl() on page 387

mvl_to_int() on page 389

mvl_to_bits() on page 391

mvl_to_mvl4() on page 393

mvl_list_to_mvl4_list() on page 396

string_to_mvl4() on page 397

6.4.3

mvl_to_int()

Purpose
Convert an mvl value to an integer

Category
Predefined routine

Syntax
mvl_to_int(mvl-list: list of mvl, mask: list of mvl): uint
Syntax Example
var ma: uint = mvl_to_int(l, {MVL_X});

Specman e Language Reference


1999-2015

389
.

Product Version 15.1


All Rights Reserved.

Parameters
mvl-list

A list of mvl values to convert to an integer value.

mask

A list of mvl values that are to be converted to 1.

Description
Converts each value in a list of mvl values into a binary integer (1 or 0), using a list of mvl mask values
to determine which mvl values are converted to 1.
When the list is less than 32 bits, it is padded with 0. When it is greater than 32 bits, it is truncated,
leaving the 32 least significant bits.

Example
var l: list of mvl = {MVL_X; MVL_X; MVL_0; MVL_1};
var ma: uint = mvl_to_int(l,{MVL_X});
// returns 12 (0b1100)
var mb: uint = mvl_to_int(l, {MVL_Z})
// returns 0

See Also

int_to_mvl() on page 390

mvl_to_bits() on page 391

mvl_to_mvl4() on page 393

mvl_list_to_mvl4_list() on page 396

6.4.4

int_to_mvl()

Purpose
Convert an integer value to a list of mvl values

Category
Predefined routine

Specman e Language Reference


1999-2015

390

Product Version 15.1


All Rights Reserved.

Syntax
int_to_mvl(value: uint, mask: mvl): list of mvl
Syntax Example
var mlist: list of mvl = int_to_mvl(12, MVL_X)

Parameters
value

An integer value to convert to a list of mvl values.

mask

An mvl value that replaces each bit in the integer that has the value 1.

Description
Maps each bit that has the value 1 to the mask mvl value, retains the 0 bits as MVL_0, and returns a list
of 32 mvl values. The returned list always has a size of 32.

Example
var mlist: list of mvl = int_to_mvl(12, MVL_X)
// returns MVL_0;..........MVL_X;MVL_X;MVL_0;MVL_0

See Also

mvl_to_int() on page 389

6.4.5

mvl_to_bits()

Purpose
Convert a list of mvl values to a list of bits

Category
Predefined routine

Specman e Language Reference


1999-2015

391
.

Product Version 15.1


All Rights Reserved.

Syntax
mvl_to_bits(mvl-list: list of mvl, mask: list of mvl): list of bit
Syntax Example
var bl: list of bit = mvl_to_bits({MVL_Z; MVL_Z; MVL_X; MVL_L}, {MVL_Z;
MVL_X})

Parameters
mvl-list

A list of mvl values to convert to bits.

mask

A list of mvl values that specifies which mvl values are to be converted to 1.

Description
Converts a list of mvl values to a list of bits, using a mask of mvl values to indicate which mvl values
are converted to 1 in the list of bits.

Example
var bl: list of bit = mvl_to_bits({MVL_Z; MVL_Z; MVL_X; MVL_L}, {MVL_Z;
MVL_X})
// returns {1; 1; 1; 0}

See Also

mvl_to_string() on page 388

mvl_to_int() on page 389

mvl_to_mvl4() on page 393

6.4.6

bits_to_mvl()

Purpose
Convert a list of bits to a list of mvl values

Specman e Language Reference


1999-2015

392

Product Version 15.1


All Rights Reserved.

Category
Predefined routine

Syntax
bits_to_mvl(bit-list: list of bit, mask: mvl): list of mvl
Syntax Example
var ml: list of mvl = bits_to_mvl({1; 0; 1; 0}, MVL_Z)

Parameters
bit-list

A list of bits to convert to mvl values.

mask

An mvl value that replaces each bit in the list that has the value 1.

Description
Maps each bit with the value 1 to the mask mvl value, retains the 0 bits as MVL_0, and returns an mvl
list that is bit-list size.

Example
var ml: list of mvl = bits_to_mvl({1; 0; 1; 0}, MVL_Z)
// returns {MVL_Z;MVL_0;MVL_Z;MVL_0}

See Also

mvl_to_bits() on page 391

6.4.7

mvl_to_mvl4()

Purpose
Convert an mvl value to a 4-value logic value

Specman e Language Reference


1999-2015

393
.

Product Version 15.1


All Rights Reserved.

Category
Predefined routine

Syntax
mvl_to_mvl4(value: mvl): mvl
Syntax Example
var m4: mvl = mvl_to_mvl4(MVL_U)

Parameters
value

An mvl value to convert to a 4-value logic value

Description
Converts an mvl value to the appropriate 4-value logic subset value.
The predefined mapping from 9-value logic to 4-value logic is:
MVL_U, MVL_W, MVL_X, MVL_N -> MVL_X
MVL_L ,MVL_0 -> 0
MVL_H, MVL_1 -> 1
MVL_Z -> MVL_Z

Example
var m4: mvl = mvl_to_mvl4(MVL_U)
// returns MVL_X

See Also

mvl_to_string() on page 388

mvl_to_int() on page 389

mvl_to_bits() on page 391

mvl_list_to_mvl4_list() on page 396

Specman e Language Reference


1999-2015

394

Product Version 15.1


All Rights Reserved.

6.4.8

convert_mvl_list_to_mvl4_list()

Purpose
Convert a list of mvl values to a list of 4-value logic subset values. This method is similar to
mvl_list_to_mvl4_list(). However, instead of creating a new list, it change the existing list provided by
user.

Category
Predefined routine

Syntax
convert_mvl_list_to_mvl4_list(mvl-list: list of mvl)
Syntax Example
var m4l: list of mvl = {MVL_N; MVL_L; MVL_H; MVL_1};
convert_mvl_list_to_mvl4_list(m41);

Parameters
mvl-list

A list of mvl values to convert to a list of 4-value logic subset values

Description
Converts each value in a list of mvl values to the corresponding 4-value logic value. Because this
method changes the existing list provided by the user instead of creating a new list, it allows for a more
aggressive dynamic memory optimization of the e code.
The predefined mapping from 9-value logic to 4-value logic is:
MVL_U, MVL_W, MVL_X, MVL_N -> MVL_X
MVL_L, MVL_0 -> MVL_0
MVL_H, MVL_1 -> MVL_1
MVL_Z -> MVL_Z

See Also

mvl_list_to_mvl4_list() on page 396

Specman e Language Reference


1999-2015

395
.

Product Version 15.1


All Rights Reserved.

6.4.9

mvl_list_to_mvl4_list()

Purpose
Convert a list of mvl values to a list of 4-value logic subset values

Category
Predefined routine

Syntax
mvl_list_to_mvl4_list(mvl-list: list of mvl): list of mvl
Syntax Example
var m4l: list of mvl = mvl_list_to_mvl4_list({MVL_N; MVL_L; MVL_H; MVL_1})

Parameters
mvl-list

A list of mvl values to convert to a list of 4-value logic subset values

Description
Converts each value in a list of mvl values to the corresponding 4-value logic value.
The predefined mapping from 9-value logic to 4-value logic is:
MVL_U, MVL_W, MVL_X, MVL_N -> MVL_X
MVL_L, MVL_0 -> MVL_0
MVL_H, MVL_1 -> MVL_1
MVL_Z -> MVL_Z

Example
var m4l: list of mvl = mvl_list_to_mvl4_list({MVL_N; MVL_L; MVL_H; MVL_1})
// returns {MVL_X; MVL_0; MVL_1; MVL_1;}

See Also

mvl_to_string() on page 388

Specman e Language Reference


1999-2015

396

Product Version 15.1


All Rights Reserved.

mvl_to_int() on page 389

mvl_to_bits() on page 391

mvl_to_mvl4() on page 393

6.4.10

string_to_mvl4()

Purpose
Convert a string to a list of 4-value logic mvl subset values

Category
Predefined routine

Syntax
string_to_mvl4(value-string: string): list of mvl
Syntax Example
mlist = string_to_mvl("8'bxz");

Parameters
value-string

A string representing MVL values, consisting of a width and base followed


by a series of characters corresponding to 9-value logic values.

Description
Converts each character in the string to the corresponding 4-value logic value. If the string contains
characters other than 0, 1, x, z, h, l, u, w or n a runtime error is issued.

Example
var mlist: list of mvl;
mlist = string_to_mvl4("8'bz");
// returns {MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_Z; MVL_Z};
mlist = string_to_mvl("8'bxz");
// returns {MVL_Z; MVL_X; MVL_X; MVL_X; MVL_X; MVL_X; MVL_X; MVL_X};

Specman e Language Reference


1999-2015

397
.

Product Version 15.1


All Rights Reserved.

See Also

string_to_mvl() on page 387

mvl_to_string() on page 388

mvl_to_mvl4() on page 393

6.5

Simple Indexed Port Declaration and Access


Operator

simple_port(index-method-type) on page 398

index()$ on page 402

6.5.1

simple_port(index-method-type)

Purpose
Access complex elements of a DUT

Category
Unit member

Syntax
port-instance-name: [list of] [direction] simple_port[(index-method-type)] of element-type [is
instance];
Syntax Examples
method_type int_string(i: int, s: string);
unit my_unit {
csp: in simple_port(int_string) of bool is instance;
};

Parameters
port-instance-name

A unique identifier you can use to refer to the port or access its value.

Specman e Language Reference


1999-2015

398

Product Version 15.1


All Rights Reserved.

direction

One of in, out, or inout. The default is inout, which means that you can read
values from and write values to this port. For an in port, you can only read
values from the port, and for an out port you can only write values to the port.

index-method-type

The method type must be explicitly defined in a separate method_type


declaration:
method_type index-method-type-name ([index-list]);
Notes

The index method type must be specified even if the indexed port has no
index list.
The method type must be of type void with no sampling event.
The index list cannot contain arguments passed by reference (using the *
syntax).
Only the following types of indexes are supported:

Scalar numeric types, signed and unsigned (up to 32 bits only)

Scalar subtypes

String

element-type

Any predefined or user-defined e type except a port type or a unit type.

is instance

is instance denotes a physical instance of the socket as a hierarchical child of


the instantiating unit. Without is instance, the declaration denotes a variable to
be used as a reference (to an instance defined elsewhere).

Description
You can use an indexed simple port to access Verilog 95 memories and multi dimensional Verilog 2001
arrays, VHDL arrays, and complex elements of a SystemVerilog DUT. For more information, see:

Accessing Verilog Memories and Multidimensional Arrays with Indexed Ports in the Specman

Integrators Guide

Accessing Complex SystemVerilog Expressions with Simple Indexed Ports in the Specman Integrators

Guide

Accessing VHDL Arrays with Indexed Ports in the Specman Integrators Guide

Notes

You must define the index method type in a separate method_type declaration. This specifies the
names and types of the variable parameters that determine, along with the HDL expression associated
with the port, which HDL element is accessed.
For certain situations, you can avoid the need for a stubs file by setting pli_access() to TRUE for a
simple indexed port. For more information, see pli_access() in the Specman Integrators Guide.

Specman e Language Reference


1999-2015

399
.

Product Version 15.1


All Rights Reserved.

When you set pli_access() to TRUE, hdl_path() is the only other port attribute that applies for the
given port.

If you do not set pli_access() to TRUE, you must define an hdl_expression() attribute for an external
indexed port. This expression can reference the hdl_path() attribute of the port as well as variable
parameters specified in the index method type.
You must use the index()$ operator to read or write an indexed port, supplying it with values for the
parameters defined in the index method type.
Internal (e2e) indexed ports are not supported.

Example 1
Verilog Code
module top;
// Verilog memory
reg [31:0] warr [15:0];
endmodule

e Code
<'
method_type ft(i:int);
unit t {
p1 : inout simple_port(ft) of uint is instance;
keep bind(p1,external); keep p1.hdl_expression() == "<p>[<i>]";
keep p1.hdl_path() == "~/top.warr";
run() is also {
start ver();
};
ver()@sys.any is {
wait delay(30);
p1.index(1)$ = 1955;
wait delay(100);
print p1.index(1)$;
assert p1.index(1)$ == 1955;
wait delay(10);
stop_run();
};
};
extend sys {
t1 : t is instance;
keep t1.hdl_path() == "~/top";
Specman e Language Reference
1999-2015

400

Product Version 15.1


All Rights Reserved.

};
'>

Example 2
This example uses pli_access().

dut.sv
module top;
reg [31:0] myreg[15:0][15:0];
initial begin
$display("[SV] myreg[3][3] = %d\n", myreg[3][3]);
#40;
$display("[SV] myreg[3][3] = %d\n", myreg[3][3]);
end
endmodule

top.e
<'
method_type dim2_method_type(i: int, j: int);
unit t

p_reg: inout simple_port(dim2_method_type) of int is instance;


keep bind(p_reg, external);
keep p_reg.hdl_path() == "myreg";
keep p_reg.pli_access() == TRUE;
run() is also {
start ver();
};
ver()@sys.any is {
wait delay(30);
p_reg.index(3,3)$ = 7777;
wait delay(100);
out("[SN] p_reg.index(3,3) port value = ", p_reg.index(3,3)$);
assert p_reg.index(3,3)$ == 7777;
stop_run();
};
};

Specman e Language Reference


1999-2015

401
.

Product Version 15.1


All Rights Reserved.

extend sys {
t1: t is instance;
keep t1.hdl_path() == "~/top";
};
'>

See Also

hdl_expression() for Indexed Ports in the Specman Integrators Guide

index()$ on page 402

Introduction to Indexed e Simple Ports in Creating e Testbenches

6.5.2

index()$

Purpose
Access an indexed port

Category
Operator

Syntax
port-exp.index(argument-list)$
Syntax Example
print sp1.index(0)$;
csp.index(1)$ = 0;
cbp.index(1,1).put(p);

Parameters
port-exp

An expression that returns an external indexed port instance.

argument-list

Values for the parameters defined in the index method type.

Description
You can use the index(argument-list)$ access operator to:

Specman e Language Reference


1999-2015

402

Product Version 15.1


All Rights Reserved.

Read or write the port value of an indexed simple port

Call a predefined method of an indexed simple port

Force or release an indexed simple port


Note

To release a port, use the index access operator without the $ character.

Indexed ports have the same predefined methods as the regular ports. For instance, indexed simple ports
have the predefined MVL methods, such as put_mvl_list(), has_x() and so on. In order to access these
predefined methods you need to apply index()$ to the method call.
Specman issues an error if the index()$ operator is applied to a regular, not indexed, port. Also, a
compile time error is issued if the argument types of the index()$ operator do not match the arguments
types listed in the index method type. The association between the arguments of the operator
index()$ and the arguments list of the index method type is by position.

Limitations

Indexed ports are currently supported for external simple ports only.
Values written by indexed ports are immediately visible, not delayed. If an indexed port is written in
one line and then read in the next line, the new value is visible.
Use of the @sim operator is not supported for indexed ports. As a result, you cannot make an e
temporal expression sensitive to value changes in SystemVerilog constructs if they are accessed only
by indexed ports.

Example 1
The following examples show how to use the index access operator to read an indexed port value.
method_type one_bit(i:bit);
...
sp1: inout simple_port(one_bit) of int is instance;
ep1: in event_port(one_bit) is instance;
ep2: out event_port(one_bit) is instance
...
print sp1.index(0)$;
wait @ep1.index(0)$;
emit ep2.index(1)$;

Example 2
The following examples show how to use the index access operator to write an indexed port value.
csp.index(1)$ = 0;
force csp.index(0)$ = 5;
Specman e Language Reference
1999-2015

403
.

Product Version 15.1


All Rights Reserved.

To release a port, use the index access operator without the $ character:
release csp.index(2);

Example 3
You can use the slice operator for indexed simple ports in the same way you do for regular simple ports:
csp.index(1)$[3:1] = 3;
force csp.index(4)$[6:3] = 4;

Example 4
You can use the index access operator in order to invoke an indexed output method port.
method type data_tcm(data: int): uint @sys.any;
method_type one_int(d:int);
...
cmp: out method_port(one_int) of data_tcm is instance;
...
var v: uint = cmp.index(31)$(-1); // Time-consuming action

See Also

Using Indexed Ports with Complex SystemVerilog Expressions in the Specman Integrators Guide

hdl_expression() for Indexed Ports in the Specman Integrators Guide

external_type() for Indexed Ports in the Specman Integrators Guide

simple_port(index-method-type) on page 398

6.6

Event Port Declarations, References, and


Access Operator

event_port on page 405

any_event_port on page 408

event_port$ on page 410

See Also

API for Controlling Event Port Sensitivity at Run Time on page 412

Specman e Language Reference


1999-2015

404

Product Version 15.1


All Rights Reserved.

6.6.1

event_port

Purpose
Transfer events between units or between simulators and units

Category
Unit member

Syntax
event-port-field-name: [list of] [direction] event_port [is instance];
Syntax Example
clk: in event_port is instance;

Parameters
event-port-field-name

A unique identifier you can use to refer to the port or access its value.

direction

One of in, out, or inout. The default is inout, which means that events can be
both emitted and sampled on the port. For a port with direction in, events can
only be sampled. For a port with direction out, events can only be emitted.

is instance

is instance denotes a physical instance of the port as a hierarchical child of


the instantiating unit. Without is instance, the declaration denotes a variable
to be used as a reference (to an instance defined elsewhere).

Note

Multi-dimensional lists (list of lists) are not supported for event ports.

Description
You can use event ports to transfer events between two e units or between an e unit and an external
object.
The attribute hdl_path() must be specified for external event ports. The edge() attribute for an external
input event port specifies the edge on which an event is generated.
You can read or write port values using the $ port access operator. See Accessing Event Ports in
Creating e Testbenches for more information.

Specman e Language Reference


1999-2015

405
.

Product Version 15.1


All Rights Reserved.

An internal event ports direction specifier can be either input, output or inout. The direction specifier is
not a when subtype determinant. This means, for example, that the following type
clk: event_port is instance;

is not the base type of


clk: out event_port is instance;

Furthermore, the following types are fully equivalent:


clk: event_port is instance;
clk: inout event_port is instance;

Limitations

Coverage on event ports is not supported.

The trace event command is not supported for event ports.

You cannot specify a temporal formula (like event_port is ...) for the definition of an out event port.

Multi-dimensional lists (list of lists) are not supported for event ports.

To work around any of these unsupported capabilities:

Define an additional event and use it to connect to the event port. Example:
ep: in event_port is instance;
keep bind(ep,external);
event e is @ep$;

Note See the chapters that describe how to use external event ports with specific languages (listed
under See Also below) for more limitations.

Example 1
References to event ports are supported. In the following example, current_clk is an event port
reference.
unit u {
clks: list of in event_port is instance;
events: list of out event_port is instance;
};
extend u {
!current_clk: in event_port;
keep current_clk == clks[0];
};

Specman e Language Reference


1999-2015

406

Product Version 15.1


All Rights Reserved.

Example 2
You can pass an event port as a parameter to a TCM. In this example, each event in a list of events is
passed as a parameter to the drive() method.
extend u {
drive(ep: out event_port) @current_clk$ is {
emit ep$;
};
run() is also {
for each in events do {
start drive(it);
};
};
};

Example 3
In the following example, an event is transferred to ext_ep when ~/top_s/transaction_done transitions
from 0 to 1.
unit u {
ext_ep: in event_port is instance;
keep bind(ext_ep,external);
keep ext_ep.hdl_path() == "transaction_done";
keep ext_ep.edge() == MVL_0_to_1;
};
extend sys {
u: u is instance;
keep u.hdl_path() == "top_s";
};

Example 4
This example shows how to configure an event port to emit based either on an HDL signal change or on
sys.any (if no simulator is attached).
<'
extend sys {
e_clock_port : out event_port is instance;
on any {
emit e_clock_port$;
};

Specman e Language Reference


1999-2015

407
.

Product Version 15.1


All Rights Reserved.

my_event_port: in event_port is instance;


keep my_event_port.hdl_path() == "~/top/clk";
dut_connected: bool;
keep dut_connected == FALSE => bind(my_event_port,e_clock_port);
keep dut_connected == TRUE => bind(my_event_port,external);
};
'>

See Also

on event-port on page 716

Introduction to e Event Ports in Creating e Testbenches

Defining Event Ports in Creating e Testbenches

hdl_path() Port Attribute in the Specman Integrators Guide

edge() in the Specman Integrators Guide

API for Controlling Event Port Sensitivity at Run Time on page 412

For more detailed information about using external event ports, see:

Creating Sampling Events in Creating e Testbenches

Creating Simulator Callbacks in Creating e Testbenches

Synchronizing Specman and SystemC with e Event Ports in the Specman Integrators Guide

Synchronizing Specman and Verilog with Event Ports in the Specman Integrators Guide

Accessing Verilog Objects of Type Real in the Specman Integrators Guide

Sensitivity to Analog Events in the Specman Integrators Guide

Using Ports to Communicate with Embedded Software in ISX User Guide

Understanding ISX Types and Type Mapping in ISX User Guide

gsa_port...event_port in ISX User Guide

6.6.2

any_event_port

Purpose
Reference an event port instance

Specman e Language Reference


1999-2015

408

Product Version 15.1


All Rights Reserved.

Category
Unit field, variable, or method parameter

Syntax
[! | var] port-reference-name: [direction] event_port
[! | var] port-reference-name: any_event_port
Syntax Example
!curr_clk: any_event_port;
!event_port_ref: out event_port;

Parameters
port-reference-name

A unique identifier.

direction

One of in, out, or inout

Description
Event port instances may be referenced by a field, a variable, or a method parameter of the same port
type or of the abstract type any_event_port. Abstract port types reference only the port kind, not the
port direction. Thus, a method parameter of type any_event_port accepts all event ports, including, for
example:
hdl_clk: in event_port is instance;
e_event: out event_port is instance;

If a port reference is a field, then it must be marked as non-generated or it must be constrained to an


existing port instance. Otherwise, a generation error results.
Port reference fields can be bound to external | undefined | empty.

Notes

You cannot apply the $ access operator to an item of type any_event_port. Abstract types do not
have any access methods. For example, the expression port_ref$ == 0 in the following code causes
a syntax error.
check_clks ( port_ref : any_event_port ) is {
if ( port_ref$ == 0) then { -- syntax error
out (sys.time, " Testing port logic comparison.");
};

Specman e Language Reference


1999-2015

409
.

Product Version 15.1


All Rights Reserved.

};

You cannot use an abstract type in a port instance

Example
unit u {
clks: list of in event_port is instance;
events: list of out event_port is instance;
};
extend u {
!current_clk: in event_port;
keep current_clk == clks[0];
};

See Also

Introduction to e Event Ports in Creating e Testbenches

event_port on page 405

6.6.3

event_port$

Purpose
Emit or be sensitive to an event associated with an event port

Category
Operator

Syntax
port-exp$
Syntax Example
...

inject()@clk$ is {
};

Specman e Language Reference


1999-2015

410

Product Version 15.1


All Rights Reserved.

Parameters
port-exp

An expression that returns an event port.

Description
The $ access operator is used to refer to the event associated with an event port. Without the $ operator
an expression of event_port type refers to the port itself, not to its event.
Note You cannot apply the $ access operator to an item of type any_event_port. Abstract types do
not have any access methods.

Example
In the following example, the use of the expression @clk$ causes the inject method to trigger when
the external signal clk changes.
unit encoder {
data: inout simple_port of list of bit is instance;
keep bind(data, external);
keep data.hdl_path() == "data";
clk: in event_port is instance;
keep bind(clk, external);
keep clk.hdl_path() == "clk";
keep clk.edge() == any_change;
data_list: list of bit;
keep data_list.size() < 32;
inject()@clk$ is {
for j from 0 to 15 {
gen data_list;
data$ = data_list;
wait cycle;
};
};
};

See Also

Introduction to e Event Ports in Creating e Testbenches

Accessing Event Ports in Creating e Testbenches

Specman e Language Reference


1999-2015

411
.

Product Version 15.1


All Rights Reserved.

6.7

API for Controlling Event Port Sensitivity at Run


Time

You can use external input event ports to make Specman sensitive to changes in HDL objects. The
methods described in this section give you the ability to turn that sensitivity on or off for given periods
of time during simulation.

6.7.1

event-port.disable() / event-port.enable()

Purpose
Deactivate or activate external input event ports.

Category
pseudo-method

Syntax
event-port-exp.disable()
event-port-exp.enable()
Syntax example:
p.disable()

Parameters
event-port-exp

An expression that returns an external input event port instance.

Description
disable() deactivates the specified external input event port.
enable() activates or reactivates the specified external input event port.
These two methods are applicable for external input event ports only. Calling these methods with a port
bound to empty is meaningless, but allowed. However, calling these methods with e2e ports or a port
bound to undefined results with an error.

Specman e Language Reference


1999-2015

412

Product Version 15.1


All Rights Reserved.

You get a warning if you call enable() with an active port or if you call disable() with a port that is
already disabled.
Notes

For a bound set of ports, any input event port in the bound setnot just the external input event
portcan call disable() or enable().
When you call disable() or enable() from a unified bound set of ports, Specman issues a warning to
let you know that the unified channel is affected.
The disable() and enable() methods can be called only after the generation phase.

Example
In this example, the deactivation of the external input event port bound to the HDL clock prevents a new
Specman tick from occurring until the reset is completed.
unit verifier {
clk: in event_port is instance;
keep bind(clk,external);
keep clk.hdl_path() == "clk";
keep clk.edge() == fall;
event clk_fall is @clk$;
reset_done : in event_port is instance;
keep reset_done.hdl_path() == "reset_done";
on clk_fall {...};
};
extend sys {
verifier is instance;
run() is also {
start main_tcm();
};
main_tcm()@sys.any is {
verifier.clk.disable();
wait @reset_done$;
verifier.clk.enable();
...
};
};

Specman e Language Reference


1999-2015

413
.

Product Version 15.1


All Rights Reserved.

See Also

Introduction to e Event Ports in Creating e Testbenches

6.8

Method Port Declarations, References, and


Access Operator

method_port on page 414

method_type method-type-name on page 415

any_method_port on page 417

method_port$() on page 418

6.8.1

method_port

Purpose
Enable invocation of abstract functions

Category
Unit member

Syntax
port-instance-name: [list of] direction method_port of method-type [is instance];
Syntax example:
convert_string: out method_port of str2uint_method_t is instance;

Parameters
port-instance-name

A unique identifier you can use to refer to the port or to invoke the actual method.
Note For input method ports, this name must match the actual name of the
associated method.

Specman e Language Reference


1999-2015

414

Product Version 15.1


All Rights Reserved.

direction

One of in or out. There is no default.

For an output port, you can invoke the method.


For an input port you can only specify the actual method to be activated.

method-type

A method_type that specifies the port semantics.

is instance

is instance denotes a physical instance of the port as a hierarchical child of the


instantiating unit. Without is instance, the declaration denotes a variable to be
used as a reference (to an instance defined elsewhere).

Description
Implements an abstraction of calling methods (time-consuming or not) in other units or in external
agents, while delaying the binding from compile time to pre-run generation time.

See Also

Introduction to e Method Ports in Creating e Testbenches

Defining External Method Ports in Creating e Testbenches

Defining Internal Method Ports in Creating e Testbenches

method_type method-type-name on page 415

any_method_port on page 417

6.8.2

method_type method-type-name

Purpose
Define method port semantics and enable notification.
Define indexed simple port semantics.

Category
Statement

Syntax
method_type method-type-name ([param-list]) [:return-type] [@sys.any];
Syntax example:
Specman e Language Reference
1999-2015

415
.

Product Version 15.1


All Rights Reserved.

method_type str2uint_method_t (s: string):uint;

Parameters
method-type-name

A legal e name. The name must be different from any other predefined type name
or user type name.

param-list

For method ports, the parameter list must match the parameter list of the e method
or external function.
For indexed simple ports, the parameter list describes the type of the indexes.
Their names must match the names in the HDL expression.

return-type

(Method ports only) The type of the returned value must match the return type of
the e method or external function.

@sys.any

(Method ports only) If the method type declaration includes the @sys.any
sampling event, this type can only be used for method ports associated with a
TCM.

Description
Method ports must be parameterized by a method type, which specifies the prototype (signature) of the
method. The method type name may also be included in runtime messages related to a specific method
port.
If you are using incremental compilation and a C file requires a method type that is neither declared or
used in the e file you are compiling with sn_compile.sh, it may be necessary to explicitly export the
method type using a C export statement.
Indexed simple ports also must be parameterized by a method type, which specifies the names and types
of the variable parameters that determine, along with the HDL expression associated with the port,
which HDL element are to be accessed.

See Also

Introduction to e Method Ports in Creating e Testbenches

Defining and Accessing Indexed Simple Ports in Creating e Testbenches

method_port on page 414

simple_port(index-method-type) on page 398

C export in the Specman Integrators Guide

Specman e Language Reference


1999-2015

416

Product Version 15.1


All Rights Reserved.

6.8.3

any_method_port

Purpose
Reference a method port instance

Category
Unit field, variable or method parameter

Syntax
[! | var] port-reference-name: direction method_port of method-type
[! | var] port-reference-name: any_method_port
Syntax Example
!in_method_port_ref: in method_port of burst_method_t;
!last_called_port: any_method_port;

Parameters
port-reference-name

A unique identifier.

direction

One of in or out

method-type

A method_type that specifies the port semantics.

Description
Method port instances may be referenced by a field, a variable, or a method parameter of the same port
type or of the abstract type any_method_port.
Abstract port types reference only the port kind, not the port direction or method type. Thus, a method
parameter of type any_method_port accepts all simple ports, including, for example:
inbox
: out method_port of deliver_method_t is instance;
inbox_int : in method_port of subscribe_method_t is instance;

If a port reference is a field, then it must be marked as non-generated or it must be constrained to an


existing port instance. Otherwise, a generation error results.
Port reference fields can be bound to external | undefined | empty.
Specman e Language Reference
1999-2015

417
.

Product Version 15.1


All Rights Reserved.

Notes

You cannot apply the $()access operator to an item of type any_method_port. Abstract types do not
have any access methods. For example, the expression port_ref()$ == 0 in the following code
causes a syntax error.
call_any_mports( port_ref : any_method_port )@clk is {
if ( port_ref$() == 0) then { -- syntax error
out (sys.time, " Method returns 0");
};
};

You cannot use an abstract type in a port instance.

Example
In the following example, port references are used as parameter in the method publish().
method_type deliver_method_t (msg_id : string);
unit publisher {
deliver1 : out method_port of deliver_method_t is instance;
deliver2 : out method_port of deliver_method_t is instance;
verify()@sys.any is {
publish(deliver1,first message);
publish(deliver2,second message);
};
publish(p:out method_port of deliver_method_t,msg : string) is {
p$(msg);
};
};

See Also

Introduction to e Method Ports in Creating e Testbenches

6.8.4

method_port$()

Purpose
Call an output method port

Specman e Language Reference


1999-2015

418

Product Version 15.1


All Rights Reserved.

Category
Operator

Syntax
port-exp$(out-method-port-param-list)
Syntax Example
u = convert_string$("32"); //calls the convert_string out method port

Parameters
port-exp

An expression that returns an output method port instance.

out-method-port-param-list

A list of actual parameters to the output method port. The number and
type of the parameters, if any, must match the method_type.

Description
The $ access operator is used to call an output method port. If you attempt to call the method via the port
without the $ operator a syntax error is issued.
Without the $ operator an expression of any type port refers to the port itself, not to its value. In
particular, an expression without the $ operator can be used for operations involving port references.
Note You cannot apply the $ access operator to an item of type any_method_port. Abstract types do
not have any access methods.

Example
method_type str2uint_method_t (s:string):uint;
unit encoder {
convert_string: out method_port of str2uint_method_t is instance;
m() is {
var u: uint;
u = convert_string$("32"); //calls the convert_string out method port
};
};

Specman e Language Reference


1999-2015

419
.

Product Version 15.1


All Rights Reserved.

See Also

Invoking Method Ports in Creating e Testbenches

6.9

Buffer Port Declarations, References, and


Access Methods

buffer_port on page 420

any_buffer_port on page 422

get() on page 424

put() on page 425

nb_get() on page 426

nb_put() on page 428

nb_insert() on page 429

nb_remove() on page 430

nb_peek() on page 431

top() on page 432

nb_top() on page 433

is_empty() on page 435

is_full() on page 436

clear_buffer() on page 437

number_of_elements() on page 438

number_of_free_elements() on page 439

6.9.1

buffer_port

Purpose
Implement an abstraction of queues with blocking get and put

Category
Unit member

Specman e Language Reference


1999-2015

420

Product Version 15.1


All Rights Reserved.

Syntax
port-instance-name: [list of] direction buffer_port of element-type [is instance];
Syntax Example
rq: in buffer_port of bool is instance;

Parameters
port-instance-name

A unique identifier you can use to refer to the port or access its value.

direction

One of in or out. There is no default. For an in port, you can only read
values from the port, and for an out port you can only write values to
the port.

element-type

Any predefined or user-defined e type except a unit or a port type.


Note A multi-dimensional list (list of lists) cannot be used as the
element type for simple or buffer e ports. Lists of lists of ports is
supported, but ports of lists of lists are not supported.

is instance

is instance denotes a physical instance of the port as a hierarchical


child of the instantiating unit. Without is instance, the declaration
denotes a variable to be used as a reference (to an instance defined
elsewhere).

Description
You can use buffer ports to insert data elements into a queue or extract elements from a queue. Data is
inserted and extracted from the queue in FIFO order. When the queue is full, write access to the port is
blocked. When the queue is empty, read access to the port is blocked.
The queue size is fixed during generation by the buffer_size() attribute and cannot be changed at
runtime. The queue size may be set to 0 for rendezvous ports.
You can read or write port values using the buffer ports predefined get() and put() methods. These
methods are time-consuming methods (TCMs). Use of the $ port access operator with buffer ports is not
supported.
Notes

External buffer ports are not supported by any simulator adapter provided by Cadence.

Specman e Language Reference


1999-2015

421
.

Product Version 15.1


All Rights Reserved.

Example
unit encoder {
rq: in buffer_port of bool is instance;
keep rq.buffer_size() == 8; -- buffer port attribute
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.2

any_buffer_port

Purpose
Reference a buffer port instance

Category
Unit field, variable or method parameter

Syntax
[! | var] port-reference-name: direction buffer_port of element-type
[! | var] port-reference-name: any_buffer_port
Syntax Example
!last_printed_port: any_buffer_port;
!in_int_buffer_port_ref: in buffer_port of int;

Parameters
port-reference-name

A unique identifier.

direction

One of in or out

element-type

The data element that can be passed through this port.

Specman e Language Reference


1999-2015

422

Product Version 15.1


All Rights Reserved.

Description
Buffer port instances may be referenced by a field, a variable, or a method parameter of the same port
type or of any_buffer_port. Abstract port types reference only the port kind, not the port direction or
data element. Thus, a method parameter of type any_buffer_port accepts all buffer ports, including, for
example:
data_length: in buffer_port of uint is instance;
data: out buffer_port of list of bit is instance;

If a port reference is a field, then it must be marked as non-generated or it must be constrained to an


existing port instance. Otherwise, a generation error results.
Port reference fields can be bound to external | undefined | empty.

Notes

You cannot call the get() or put() methods of an item of type any_buffer_port. Abstract types do
not have any access methods. For example, the expression port_ref.get() in the following code
causes a syntax error.
check_queues ( port_ref : any_buffer_port )@clk is {
if ( port_ref.get() == 0) then { -- syntax error
out (sys.time, "Problem with queues");
};
};

You cannot use an abstract type in a port instance.

Example
The print_port() method in the following example can be called with any buffer port. The iterate()
method shows an alternative way to print a list of ports.
unit u {
plist: list of in buffer_port of int is instance;
!last_printed_port: any_buffer_port; // A field, so must be
// non-generated
print_port(p: any_buffer_port) is { // A method parameter
print p;
// Prints the port's e path, agent name, and so on
last_printed_port = p;
};
iterate() is {
for each in plist {
var buffer_port_ref: any_buffer_port;
buffer_port_ref = it;
Specman e Language Reference
1999-2015

423
.

Product Version 15.1


All Rights Reserved.

print_port(buffer_port_ref);
};
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.3

get()

Purpose
Read and remove data from an input buffer port queue

Category
Predefined TCM for buffer ports

Syntax
in-port-instance-name.get(): port element type
Syntax Example
rec_cell = in_port.get();

Description
Reads a data item from the buffer port queue and removes the item from the queue.
Since buffer ports use a FIFO queue, get() returns the first item that was written to the port.
The thread blocks upon get() when there are no more items in the queue.
If the queue is empty, or if it has a buffer size of 0 and no put() has been done on the port since the last
get(), then the get() is blocked until a put() is done on the port.
The number of consecutive get() actions that is possible is limited to the number of items inserted by
put().
Specman e Language Reference
1999-2015

424

Product Version 15.1


All Rights Reserved.

Example
unit consumer {
cell_in: in buffer_port of atm_cell is instance;
current_cell: atm_cell;
update_cell() @clk$ is {
current_cell = cell_in.get();
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.4

put()

Purpose
Write data to an output buffer port queue

Category
Predefined TCM for buffer ports

Syntax
out-port-instance-name.put(data: port-element-type)
Syntax Example
out_port.put(trans_cell);

Parameters
data

A data item of the port element type.

Description
Writes a data item to the output buffer port queue. The sampling event of this TCM is sys.any.
Specman e Language Reference
1999-2015

425
.

Product Version 15.1


All Rights Reserved.

The new data item is placed in a FIFO queue in the output buffer port.
If the queue is full, or if it has a buffer size of 0 and no get() has been done on the port since the last
put(), then the put() is blocked until a get() is done on the port.
The number of consecutive put() actions that is possible is limited to the buffer size.
The thread blocks upon put() when there is no more room in the queue, that is, when the number of
consequent put() operations exceeds the buffer_size() of the port instance.

Example
unit producer {
clk: in event_port is instance;
cell_out: out buffer_port of atm_cell is instance;
write_cell_list(atm_cells: list of atm_cell) @clk$ is {
for each in atm_cells do {
cell_out.put(it);
};
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

pass_by_pointer() in Creating e Testbenches

6.9.5

nb_get()

Purpose
Read and remove data from an input buffer port queue without blocking

Category
Predefined method for buffer ports

Syntax
in-port-instance-name.nb_get(var: port-element-type) : bool

Specman e Language Reference


1999-2015

426

Product Version 15.1


All Rights Reserved.

Syntax Example
nb_get_result = in_port.nb_get(rec_cell);

Parameters
var

A method parameter of the port element type.

Description
Reads a data item from the buffer port queue and removes the item from the queue, without blocking.

If there are data items in the queue:


a.

The item at the top of the queue is assigned to the method parameter.

b.

This item is removed from the queue.

c.

The method call returns TRUE.

If the queue is empty:


a.

The parameter remains untouched.

b.

The method call returns FALSE

Example
unit consumer {
cell_in: in buffer_port of atm_cell is instance;
current_cell: atm_cell;
update_cell() @clk$ is {
if (cell_in.nb_get(current_cell)){
analyze_cell();
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

Specman e Language Reference


1999-2015

427
.

Product Version 15.1


All Rights Reserved.

6.9.6

nb_put()

Purpose
Write data to an output buffer port queue without blocking

Category
Predefined method for buffer ports

Syntax
out-port-instance-name.nb_put(data: port-element-type) : bool
Syntax Example
nb_put_result = out_port.nb_put(trans_cell);

Parameters
data

A data item of the port element type.

Description
Writes a data item to the output buffer port queue, without blocking:

If there is room in the queue:


a.

The data value is added to the queue.

b.

The method call returns TRUE.

If the queue is full, the method call returns FALSE.

Example
unit producer {
clk: in event_port is instance;
cell_out: out buffer_port of atm_cell is instance;
write_cell_list(atm_cells: list of atm_cell) @clk$ is {
for each in atm_cells do {
while not (cell_out.nb_put(it)){
wait [1];
Specman e Language Reference
1999-2015

428

Product Version 15.1


All Rights Reserved.

};
};
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.7

nb_insert()

Purpose
Insert an item into an out buffer port queue

Category
Predefined method for out buffer ports

Syntax
out-port-instance-name.nb_insert(index: uint, value value-type) : bool
Syntax Example
my_bool_port.nb_insert(location, TRUE);

Parameters
out-port-instance-name

The name for an out buffer port instance.

index

The number of the index location where the new queue item is to be inserted.

value value-type

The value and type of the queue item to be inserted at the index location.

Description
Inserts a new item of value-type into the out buffer port queue at the given index location. Applies the
value to the new item. All items in the queue to the right of the inserted item move one place right.

Specman e Language Reference


1999-2015

429
.

Product Version 15.1


All Rights Reserved.

This method returns TRUE if it succeeds. The method returns FALSE if it fails, for example because the
buffer queue is already full or because the insertion would cause the queue to be larger than the value set
by the buffer_size() attribute.
This method applies for out e buffer ports only.

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

nb_remove() on page 430

nb_peek() on page 431

6.9.8

nb_remove()

Purpose
Removes an item from the buffer queue and assigns the value to a given parameter.

Category
Predefined method for in or out buffer ports

Syntax
port-instance-name.nb_remove(index: uint, value*value-type) : bool
Syntax Example
var removal_list: list of int;
my_list_of_int_port.nb_remove(2, removal_list);

Parameters
port-instance-name

The name for an in or out buffer port instance.

index

The number of the index location for the item to be removed.

value*value-type

The value and type to be assigned.

Specman e Language Reference


1999-2015

430

Product Version 15.1


All Rights Reserved.

Description
Removes the given item from the buffer queue and assigns the given value to the given parameter. All
items in the queue to the right of the deleted item move one place left.
This method returns TRUE if it succeeds. The method returns FALSE if it fails, for example because the
buffer queue was empty or because the index location did not contain an item.
This method applies for in or out e buffer ports.

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

nb_insert() on page 429

nb_peek() on page 431

6.9.9

nb_peek()

Purpose
Get the item value into the given parameter variable without removing it from the buffer queue.

Category
Predefined method for in buffer ports

Syntax
in-port-instance-name.nb_peek(index: uint, value*value-type) : bool
Syntax Example
var needed_num: int;
mv_int_port.nb_peek(5, needed_num);

Parameters
in-port-instance_name

The name for the in buffer port instance.

index

The number of the index location.

Specman e Language Reference


1999-2015

431
.

Product Version 15.1


All Rights Reserved.

value*value-type

The value and its type to be applied to the item at the index location.

Description
Gets the given value to the item at the specified index location in the buffer queue and does not delete
the item.
This method returns TRUE if it succeeds. The method returns FALSE if it fails, for example if no item
exists at the given index location.
This method applies for in e buffer ports only.

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

nb_insert() on page 429

nb_remove() on page 430

6.9.10

top()

Purpose
Read data from an input buffer port queue without removing it

Category
Predefined TCM for buffer ports

Syntax
in-port-instance-name.top(): port element type
Syntax Example
current_cell = in_port.top();

Description
Reads a data item from top of the buffer port queue without removing the item from the queue.
Specman e Language Reference
1999-2015

432

Product Version 15.1


All Rights Reserved.

Because buffer ports use a FIFO queue, top() returns the first item that was written to the port.
The thread blocks upon top() when there are no more items in the queue.
If the queue is empty, then the top() is blocked until a put() is done on the port. Unlike get(), the item
read is not removed from the buffer.
Note Using top() with a port with a rendezvous (zero size) buffer queue causes a run time error
because the concept of a top queue item in a zero-sized queue is meaningless.

Example
unit consumer {
cell_in: in buffer_port of atm_cell is instance;
current_cell: atm_cell;
!counter : int;
sample_cell() @clk$ is {
var sampled_cell : atm_cell = cell_in.top();
if (sampled_cell.payload_type == 3) {
counter += 1;
};
};
update_cell() @clk$ is {
current_cell = cell_in.get();
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.11

nb_top()

Purpose
Read data from an input buffer port queue without blocking

Category
Predefined method for buffer ports

Specman e Language Reference


1999-2015

433
.

Product Version 15.1


All Rights Reserved.

Syntax
in-port-instance-name.nb_top(var : port element type) : bool
Syntax Example
nb_top_result = in_port.nb_top(curr_cell);

Description
Reads a data item from the buffer port queue, without removing the item and without blocking.

If there are data items in the queue:


a.

The item at the top of the queue is assigned to the method parameter.

b.

Unlike nb_get(), this item is not removed from the queue.

c.

The method call returns TRUE.

If the queue is empty:


a.

The parameter remains untouched.

b.

The method call returns FALSE

Note Using nb_top() with a port with a rendezvous (zero size) buffer queue causes a run time error
because the concept of a top queue item in a zero-sized queue is meaningless.

Example
unit consumer {
cell_in: in buffer_port of atm_cell is instance;
current_cell: atm_cell;
!counter : int;
sample_cell() @clk$ is {
var sampled_cell : atm_cell;
if ((cell_in.nb_top(sampled_cell)) and \
(sampled_cell.payload_type == 3)) {
counter += 1;
};
};
update_cell() @clk$ is {
current_cell = cell_in.get();
};
};

Specman e Language Reference


1999-2015

434

Product Version 15.1


All Rights Reserved.

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.12

is_empty()

Purpose
Check if an input buffer port queue is empty

Category
Pseudo-method for buffer ports

Syntax
in-port-instance-name.is_empty(): bool
Syntax Example
var readable: bool;
readable = not cell_in.is_empty();

Description
Returns TRUE if the input port queue is empty.
Returns FALSE if the input port queue is not empty.
Note When buffer_size() is set to 0 (rendezvous-style handshaking protocol) and no put() has been
done on the port since the last get(), then the get() is blocked until a put() is done on the port. In this
situationthat is when the buffer size is set to 0is_empty() returns TRUE only when the buffer is
inside a blocking get() waiting for a subsequent put().

Example
unit consumer {
cell_in: in buffer_port of atm_cell is instance;
clk: in event_port is instance;
check_and_read(atm_cell): atm_cell @clk$ is {
if cell_in.is_empty() {
// No data is available - avoid blocking:
Specman e Language Reference
1999-2015

435
.

Product Version 15.1


All Rights Reserved.

dut_error("No atm cell is available");


}
else {
// Read data from the port:
return cell_in.get();
};
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.13

is_full()

Purpose
Check if an output buffer port queue is full

Category
Pseudo-method for buffer ports

Syntax
out-port-instance-name.is_full(): bool
Syntax Example
var overflow: bool;
overflow = cell_out.is_full();

Description
Returns TRUE if the output port queue is full.
Returns FALSE if the output port queue is not full.

Specman e Language Reference


1999-2015

436

Product Version 15.1


All Rights Reserved.

Note When buffer_size() is set to 0 (rendezvous-style handshaking protocol) and no get() has been
done on the port since the last put(), then the put() is blocked until a get() is done on the port. In this
situationthat is when the buffer size is set to 0is_full() returns TRUE only when the buffer is inside
a blocking put() waiting for a subsequent get().

Example
unit producer {
cell_out: out buffer_port of atm_cell is instance;
clk: in event_port is instance;
check_and_write(cell: atm_cell)@clk$ is {
if cell_out.is_full() {
// Cannot write to the port without being blocked
dut_error("Overflow in atm cells queue");
}
else {
// Write data to the port
cell_out.put(cell);
};
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.14

clear_buffer()

Purpose
Clears the port queue

Category
Predefined method for buffer ports

Syntax
port-instance-name.clear_buffer()

Specman e Language Reference


1999-2015

437
.

Product Version 15.1


All Rights Reserved.

Syntax Example
cell_in.clear_buffer();

Description
Removes all data items from the buffer queue.

Example
unit consumer {
cell_in: in buffer_port of atm_cell is instance;
current_cell: atm_cell;
update_cell() @clk$ is {
current_cell = cell_in.get();
};
reset_buffer() is {
cell_in.clear_buffer();
assert cell_in.is_empty();
};
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.15

number_of_elements()

Purpose
Get the number of current data items in the buffer queue

Category
Predefined method for buffer ports

Syntax
port-instance-name.number_of_elements() : uint

Specman e Language Reference


1999-2015

438

Product Version 15.1


All Rights Reserved.

Syntax Example
elem_num = bport.number_of_elements();

Description
Returns the number of data items that are currently in the queue.

Example
unit consumer {
cell_in: in buffer_port of atm_cell is instance;
current_cell: atm_cell;
force_gets() @clk$ is {
while (cell_in.number_of_elements() > 2) {
assert (cell_in.nb_get(current_cell) == TRUE);
analyze_packet();
};
};
analyze_packet() is {
...;
};
};

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.9.16

number_of_free_elements()

Purpose
Get the number of data items that can be written to the buffer queue, before the queue becomes full

Category
Predefined method for buffer ports

Syntax
port-instance-name.number_of_free_elements() : uint

Specman e Language Reference


1999-2015

439
.

Product Version 15.1


All Rights Reserved.

Syntax Example
elems_to_add = bport.number_of_free_elements();

Description
Returns the number of data items that currently can be written into the buffer queue operations.

Example
unit consumer {
cell_out: out buffer_port of atm_cell is instance;
fill_buffer() is {
var curr_cell : atm_cell;
var elements_to_add : uint = cell_out.number_of_free_elements();
for I from 1 to elements_to_add{
gen curr_cell;
assert (cell_out.nb_put(curr_cell) == TRUE);
};
};
};

Introduction to e Buffer Ports in Creating e Testbenches

Buffer Port Declarations, References, and Access Methods on page 420

6.10 e Port Binding Declarations and Methods

bind() on page 441

connect_pointers() on page 445

connect_ports() on page 446

check_generation() on page 448

do_bind() on page 449

do_bind_unit() on page 451

connect() for e2e Method Ports on page 454

remap_hdl_path() on page 457

disconnect() on page 459

disconnect_bound_set() on page 460

get_bound_set() on page 461

is_connected() on page 463

Specman e Language Reference


1999-2015

440

Product Version 15.1


All Rights Reserved.

The connect_pointers() Method of sys on page 464

The connect_ports() Method of sys on page 467

The check_generation() Method of sys on page 469

See Also

connect() for e TLM Interface Ports on page 479

6.10.1

bind()

Purpose
Connect ports

Category
Predefined routine

Syntax
keep bind(port-exp1, port-exp2) [== TRUE];
keep bind(port-exp1, external) [== TRUE];
keep bind(port-exp1, empty | undefined) [== TRUE];
Syntax Example
keep bind(bfm.data_in, driver.data_out);

Parameters
port-exp1, port-exp2

One or two expressions of port type. If two expressions are given and
the port types are compatible, the two port instances are connected.

external

Defines a port as connected to a simulated object.

empty

Defines a disconnected port. Runtime accessing of a port with an empty


binding is allowed.

undefined

Defines a disconnected port. Runtime accessing of a port with an


undefined binding causes an error.

Specman e Language Reference


1999-2015

441
.

Product Version 15.1


All Rights Reserved.

Description
You can use the bind() routine in a keep constraint to create a declarative binding that connects a port to
another e port or to an external simulated object. Ports can also be defined explicitly as disconnected
with empty or undefined.
You can also call the bind() routine procedurally to determine if two ports are connected or if a port is
connected to an external object. For external, bind() returns TRUE only if the specified port is bound to
external, not if it is in a bound set that also has external connections.

Notes

It is an error to declare a port disconnected in more than one way. For example:
-- the following is an error
keep bind(p1, empty);
keep bind(p1, undefined);

For bindings with the syntax keep bind(port-exp1, port-exp2), the order of the port expressions does
not matter.
If a port is declared both connected and disconnected, the port connection declaration always
overrides the explicit port disconnection.
Each of the kinds (empty/external/undefined/port-exp) is resolved separately by the solver. Thus, for
example, the constraint keep soft bind(clk_ip, p1); can be overridden by the hard constraint
keep bind(clk_ip, p2);, but not by keep soft bind(clk_ip, external);.
The binding is ultimately set according to priority (connected port overrides empty/undefined, and
an error is issued if both empty and undefined are set).

Example 1

Valid Binding for Buffer Ports

<'
unit driver_u {
data_out: out buffer_port of int(bits:16) is instance;
keep data_out.buffer_size() == 20;
};
unit bfm_u {
data_in: in buffer_port of int(bits:16) is instance;
};
extend sys {
driver: driver_u is instance;
bfm: bfm_u is instance;
keep bind(bfm.data_in, empty); // data_in is explicitly disconnected
};
'>
<'
extend sys {
Specman e Language Reference
1999-2015

442

Product Version 15.1


All Rights Reserved.

keep bind(bfm.data_in, driver.data_out);// data_in is bound to


// data_out, over-riding
// previous empty binding
};
'>

Example 2

Valid Binding for Simple External Ports

unit monitor_u {
data_in: in simple_port of int is instance;
};
extend sys {
monitor: monitor_u is instance;
keep bind(monitor.data_in, external);
// data_in is bound
keep monitor.data_in.hdl_path() == "data"; // to external signal "data"
};

Example 3

Valid Multiple Binding Examples for Simple Ports

unit bfm_u {
data_out: out simple_port of int is instance;
};
unit scoreboard_u {
stim_in: in simple_port of int is instance;
};
extend sys {
bfm: bfm_u is instance;
scoreboard: scoreboard_u is instance;
keep bind(bfm.data_out, external);
// data_out is bound
keep bfm.data_out.hdl_path() == "data"; // to external signal "data"
keep bind (bfm.data_out, scoreboard.stim_in); // data_out is also bound
// to scoreboard.stim_in
};

Example 4

Valid Binding Example for Method Ports

method_type write_transaction_method_t (t: xyz_transaction): bool;


method_type report_transaction_method_t (t: xyz_transaction);
unit xyz_client {
write: out method_port of write_transaction_method_t is instance;
keep bind(write, external);
// external binding
keep write.hdl_path() == "transactor";
keep write.hdl_convertor() == "(transaction: TRCONV)";
mark: out method_port of report_transaction_method_t is instance;
};
extend sys {
client: xyz_client is instance;

Specman e Language Reference


1999-2015

443
.

Product Version 15.1


All Rights Reserved.

keep client.hdl_path() == "~/ip";


keep client.agent() == "systemc";
server: xyz_server is instance;
keep bind(client.mark, server.scoreboard);

// internal binding

};

Example 5

Invalid Bindings

buf_in2: in buffer_port of int(bits:32) is instance;


buf_out2: out buffer_port of int(bits:16) is instance;
keep bind(buf_in2, buf_out2); // Invalid; different bit size
buf_in3: in buffer_port of packet is instance;
buf_out3: out buffer_port of small packet is instance;
keep bind(buf_in3, buf_out3); // Invalid; different subtypes

Example 6

Example of Procedural Call to bind()

The bind() routine can also be called in procedural code. It returns TRUE if the two ports are bound
directly or if they are part of the same bound set. For example:
connect_ports() is also {
if (!bind(p, q)) then {
do_bind(p, q);
};
};

Example 7

Example of Procedural Call to bind()

You can also call bind() with empty, undefined and external. For external, bind() returns TRUE only
if the specified port is bound to external, not if it is in a bound set that also has external connections. For
example:
connect_ports() is also {
do_bind(p, q);
do_bind(q, external);
print bind(p, external); --prints FALSE
print bind(q, external); --prints TRUE
};

See Also

Introduction to e Buffer Ports in Creating e Testbenches

Specman e Language Reference


1999-2015

444

Product Version 15.1


All Rights Reserved.

do_bind() on page 449

6.10.2

connect_pointers()

Purpose
Connect unit references (pointers)

Category
Predefined method for any unit

Syntax
connect_pointers() is also {...}
Syntax Example
connect_pointers() is also {
bfm.driver = driver;
driver.bfm = bfm;
};

Description
When you issue a test, start, or generate command from the Specman command line, after the unit tree
is generated and calls to post_generate() are complete, the sys.connect_pointers() method is called.
Then, every unit under sys is processed in depth-first field order and its connect_pointers() method
called before proceeding to the next unit instance.
See Figure 23-1 on page 1142 for more information on test phases. See The connect_pointers() Method
of sys on page 464 for an explanation of depth-first field order.
This method is initially empty. You can extend this method to set unit references.

Notes

You must mark all unit pointers that are set procedurally with a !. Failing to do so while failing to
constrain them results in a generation-time error message:
Cannot generate xxx - not an instance

Specman e Language Reference


1999-2015

445
.

Product Version 15.1


All Rights Reserved.

Because connect_pointers() is called after the unit tree for the VE is generated and after
post_generate() is called, any reference assigned in connect_pointers() must not be used in
constraints or in post_generate(). In general, connect_pointers() is recommended only to create
cross references between sibling units. See Propagating Data when Generating the VE in the Specman
Generation User Guide for more information.

Example
Note The dependent fields, bfm.driver and driver.bfm in this example, must be marked as
do-not-generate.
extend agent {
bfm: ex_atm_bfm is instance;
driver: ex_atm_sequence_driver is instance;
connect_pointers() is also {
bfm.driver = driver;
driver.bfm = bfm;
};
};

See Also

The connect_pointers() Method of sys on page 464

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

Port Binding and Rule Checking During Generation in Creating e Testbenches

6.10.3

connect_ports()

Purpose
Connect ports procedurally

Category
Predefined method for any unit

Syntax
connect_ports() is also {...}
Syntax Example
connect_ports() is also {
Specman e Language Reference
1999-2015

446

Product Version 15.1


All Rights Reserved.

do_bind(driver.bfm.data_in, bfm.driver.data_out);
};

Description
When you issue a test, start, or generate command from the Specman command line, after the unit tree
is generated and calls to connect_pointers() are complete, the sys.connect_ports() method is called.
Then, every unit under sys is processed in depth-first field order and its connect_ports() method called
before proceeding to the next unit instance. See The connect_pointers() Method of sys on page 464 for
more information on depth-first order. See Figure 23-1 on page 1142 for more information on test
phases.
This method is initially empty. You can extend this method to connect ports procedurally using the
do_bind() routine to connect ports. You can also call other routines to disconnect or query bindings,
such as do_bind_unit(), disconnect(), disconnect_bound_set(), get_bound_set() and is_connected().
Sometimes you need to set final values that depend on unit references, either by assignment or by a gen
action. You can do this in connect_ports().
Note You cannot use the port values from within connect_ports(). Ports only become operational at
after the generation phase completes.

Example 1

Simple Example of connect_ports()

unit my_sequence_driver_u {
!bfm: my_bfm_u;
data_out: out buffer_port of uint is instance;
keep data_out.buffer_size() == 20;
};
unit my_bfm_u {
!driver: my_sequence_driver_u;
data_in: in buffer_port of uint is instance;
};
extend sys {
driver: my_sequence_driver_u is instance;
bfm: my_bfm_u is instance;
connect_pointers() is also {
bfm.driver = driver;
driver.bfm = bfm;
};
connect_ports() is also {
do_bind(driver.bfm.data_in, bfm.driver.data_out);
};
};

Specman e Language Reference


1999-2015

447
.

Product Version 15.1


All Rights Reserved.

Example 2

Setting Final Values

This example shows how to set final values when unit references have been created procedurally. You
cannot use post_generate() to set final values in this case, since calls to post_generate() complete
before the unit references are created.
extend my_module_e_uvc {
-- The following two fields are set by connect_ports()
!serial_kind: serial_kind_t;
!initial_length: int;
connect_ports() is also {
-- Assumes that the pointer to the corresponding serial interface
-- e UVC (a field called serial_interface) has already been set by
-- connect_pointers()
-- Procedural assignment using a unit reference
serial_kind = serial_interface.kind;
-- Random generation using a cross pointer
gen initial_length keeping {it < serial_interface.max_length};
};
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

The connect_ports() Method of sys on page 467

6.10.4

check_generation()

Purpose
Implement user-defined checks, including connection checks

Category
Predefined method for any unit

Syntax
check_generation() is also {...}
Specman e Language Reference
1999-2015

448

Product Version 15.1


All Rights Reserved.

Syntax Example
check_generation() is also {
assert bind(driver.data_out, bfm.data_in);
};

Description
When you issue a test, start, or generate command from the Specman command line, after the unit tree
is generated and calls to connect_ports() are complete, the sys.check_generation() method is called.
Then, every unit under sys is processed in depth-first field order and its check_generation() method
called before proceeding to the next unit instance. See The connect_pointers() Method of sys on page
464 for more information on depth-first order. See Figure 23-1 on page 1142 for more information on
test phases.
This method is initially empty. You can extend this method to implement user-defined checks, such as
port binding or final value checks.

Example
unit external_interface {
// external_clk is intended to be bound to some external clock
external_clk : in simple_port of bool is instance;
check_generation() is also {
assert bind(external_clk, external);
};
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

The check_generation() Method of sys on page 469

6.10.5

do_bind()

Purpose
Connect ports

Specman e Language Reference


1999-2015

449
.

Product Version 15.1


All Rights Reserved.

Category
Predefined routine

Syntax
do_bind(port-exp1, port-exp2[,...]);
do_bind(port-exp1, external);
do_bind(port-exp1, empty | undefined);
Syntax Example
do_bind(driver.bfm.data_in, bfm.driver.data_out);

Parameters
port-exp1, port-exp2[,...]

One or more expressions of port type. If two expressions are given and
the port types are compatible, the two port instances are connected.

external

Defines a port as connected to an external object.

empty

Defines a disconnected port. Runtime accessing of a port with an empty


binding is allowed.

undefined

Defines a disconnected port. Runtime accessing of a port with an


undefined binding causes an error

Description
By calling the do_bind() routine, you procedurally connect a port to one or more e ports or to one or
more external simulated object. Ports can also be left explicitly disconnected with empty or undefined.

Notes

The do_bind() method can only be called during the connect_ports() sub-phase. Calling it at any
other time results in an error message.
It is an error to declare a port disconnected in more than one way. For example:
-- the following is an error
do_bind(p1, empty);
do_bind(p1, undefined);

Specman e Language Reference


1999-2015

450

Product Version 15.1


All Rights Reserved.

Example
In the following example, connect_ports() calls do_bind(). The parameters of the do_bind() routine
are pointers set during the connect_pointers sub-phase of generation. This is a typical use of do_bind().
unit my_sequence_driver_u {
!bfm: my_bfm_u;
data_out: out buffer_port of uint is instance;
keep data_out.buffer_size() == 20;
};
unit my_bfm_u {
!driver: my_sequence_driver_u;
data_in: in buffer_port of uint is instance;
};
extend sys {
driver: my_sequence_driver_u is instance;
bfm: my_bfm_u is instance;
connect_pointers() is also {
bfm.driver = driver;
driver.bfm = bfm;
};
connect_ports() is also {
do_bind(driver.bfm.data_in, bfm.driver.data_out);
};
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

bind() on page 441

connect_ports() on page 446

6.10.6

do_bind_unit()

Purpose
Bind all of the ports of a unit at once

Category
Predefined routine

Specman e Language Reference


1999-2015

451
.

Product Version 15.1


All Rights Reserved.

Syntax
do_bind_unit(unit-exp1, unit-exp2[, explicit-mappings]);
do_bind_unit(unit-exp1, external);
do_bind_unit(unit-exp1, empty | undefined);
Syntax Example
do_bind_unit(agent.monitor_int, monitor);

Parameters
unit-exp1, unit-exp2

One or more expressions of unit instance type. If two expressions are given
and no explicit mappings are given, each port instance in the first unit
instance is bound to the port instance of the same name in the second unit.
Note If there is no port in the second unit of the same name as in the first
unit, an error is issued.

explicit-mappings

A comma-separated list of pairs of fields to be bound explicitly, not by name.


The second item in the pair can be one of the keywords external, empty,
undefined, or none. none indicates that the current binding of the port should
not be modified. If none is specified for a port, you cannot subsequently
repeat the port in the explicit mappings list with a different mapping.
Note The fields should match the static type of the unit, otherwise a
load-time error is issued.

external

Binds all port instances in the unit to external objects.

empty

Defines all port instances in the unit as disconnected. Runtime accessing of a


port with an empty binding is allowed.

undefined

Defines all port instances in the unit as disconnected. Runtime accessing of a


port with an undefined binding causes an error

Description
Defines all port instances in a unit in one of the following ways:

As bound by name to the port instances in a second unit

As bound by explicit mapping to the port instances in a second unit

As bound to external objects

Specman e Language Reference


1999-2015

452

Product Version 15.1


All Rights Reserved.

As disconnected

Implicit mappings, including type matching checks, are performed during elaboration. Explicit mapping
is checked at load time, using the static types of the units.
Port connections made with do_bind_unit() are identical to those created with keep bind() or
do_bind(). You disconnect them and query them with the same routines, and you can create additional
multiple bindings, following the general rules for multiple bindings.
Port references can be mapped to external | undefined | empty with this pseudo-routine.

Limitations

The do_bind_unit() method can only be called during the connect_ports() sub-phase. Calling it at
any other time results in an error message.
do_bind_unit() is not symmetrical. do_bind_unit(X, Y) is not the same as do_bind_unit(Y, X).
do_bind_unit() considers all port instances of unit1, but unit2 may have ports that are not considered.
Currently, the pseudo-routine do_bind_unit() cannot receive as its first argument a unit that has an
instance field of the type list of port.

Example 1
Assume unit X has ports p1 and p2, while unit Y has ports p1, p2, and p3. In that case:
do_bind_unit(X, Y);

is the same as:


do_bind(X.p1, Y.p1); do_bind(X.p2, Y.p2);

No port binding of Y.p3 is created by this call to do_bind_unit().

Example 2
Assume unit X has ports p1 and p2, while unit Y has ports p1, p2, and p3. In that case:
do_bind_unit(X, Y, p1, p3);

is the same as:


do_bind(X.p1, Y.p3); do_bind(X.p2, Y.p2);

The port binding of Y.p1, if any, remains unchanged.


No port binding of Y.p1 is created by this call to do_bind_unit().

Specman e Language Reference


1999-2015

453
.

Product Version 15.1


All Rights Reserved.

Example 3
You can also specify undefined, empty, external or none in list of port instances to be bound. For
example, the list p1, p3, p2, external makes the following bindings:

unit-exp1.p1<=>unit-exp2.p3

unit-exp1.p2=>external

All other remaining pairs of port instances with the same names, for example:

unit-exp1.p5<=>unit-exp2.p5

unit-exp1.p6<=>unit-exp2.p6

As another example, if X and Y each has the ports p1, p2, p3 then
do_bind_unit(X, Y, p1, none)

binds X.p2 to Y.p2 and X.p3 to Y.p3 but does nothing with X.p1 or Y.p1.

See Also

Using Bundled Binding to Bind All Ports for a Unit at One Time in Creating e Testbenches

do_bind() on page 449

6.10.7

connect() for e2e Method Ports

Purpose
Connect e2e method ports directly

Category
Method port pseudo-method

Syntax
port-exp1.connect(port-exp2);
port-exp1.connect(empty | undefined);
Syntax Examples
env.agent[1].outport.connect(env.agent[2].inport);
env.agent.monitor.outport.connect(empty);
Specman e Language Reference
1999-2015

454

Product Version 15.1


All Rights Reserved.

Parameters
port-exp1

An output e2e method port expression (that is not of type


any_method_port).
Note port-exp1 can be an output method port onlynot an input
method port.

port-exp2

An e2e method port expression, input or output (that is not of type


any_method_port).

empty

Defines a disconnected method port. In this case, invoking a method on


port-exp1 is like calling an empty port.
When port-exp1 is bound to empty, this must be the only outbound
connection it has.

undefined

Defines a disconnected method port. In this case, invoking a method on


port-exp1 causes a run-time error.
When port-exp1 is bound to undefined, this must be the only outbound
connection it has.

Description
The connect() method creates a directed outbound connection from port-exp1. The method types for
port-exp1 and port-exp2 must be identical.
Directed binding for method ports differs from regular binding for method portsfor example, created
with keep bind()in that directed binding for multiple method ports does not result in a star topology,
but rather in a network of directed connections. In a star topology, all output ports are bound to all input
ports in the network. In a directed network, an output port is connected only to the input ports specified
with connect().
Note connect() for method ports is supported for e2e method ports only. When used with TLM 2.0
sockets or interface ports, however, connect() is supported for both e2e and external ports.

Binding Rules
At elaboration phase, checks are done to verify that the created network connection is legal. The checks
depend on whether the method type supports multiple servers. A method type supports multiple servers
if it is non TCM, has no return value and has no by reference parameters.
In addition to that, cycles are not allowed, meaning that a port cannot be directly or indirectly connected
to itself.

Specman e Language Reference


1999-2015

455
.

Product Version 15.1


All Rights Reserved.

Resolving Multiple Connections to the Same Input Method Port


Even if an output method port is connected to an input method port via several paths, the associated
method is invoked only once.
For example, assume that p1, p2, and p3 are three output method ports, and i1 is an input method port.
The following code:
p1.connect(p2);
p1.connect(p3);
p2.connect(i1);
p3.connect(i1);

Creates the configuration shown below. Even though p1 is connected to i1 through p2 and through p3,
the method invoked from i1 will be invoked once only.

p2

p1

i1

p3

Mixing Directed and Non-Directed Binding


In general, it is not recommended to mix directed and non-directed binding:
Non-directed binding can be used only before any directed binding is used. If method port is bound first
with non-directed binding and then with directed binding, the non-directed binding is converted to
directed binding. This is done by creating a directed connection from any output method port to any
input method port in the bound set.
Because non-directed binding cannot be used after directed binding, the following holds for any method
port bound with connect():

It is illegal to consequently bind that port with do_bind() or do_bind_unit().


It is illegal to consequently disconnect that port with port.disconnect() or
port.disconnect_bound_set().

Specman e Language Reference


1999-2015

456

Product Version 15.1


All Rights Reserved.

Example
In the following example,outport1 is connected to inport1 and inport2, and outport2 is connected to
inport2 and inport3.
extend sys {
outport1: out method_port of packet_type is instance;
outport2: out method_port of packet_type is instance;
inport1: in method_port of packet_type is instance;
inport2: in method_port of packet_type is instance;
inport3: in method_port of packet_type is instance;
connect_ports() is also {
outport1.connect(inport1);
outport1.connect(inport2);
outport2.connect(inport2);
outport2.connect(inport3);
};

See Also

Multiple Bindings for Method Ports in Creating e Testbenches

6.10.8

remap_hdl_path()

Purpose
Change the external object to which a port instance is bound

Category
Port pseudo-method

Syntax
port-exp.remap_hdl_path(new-hdl-path);
Syntax Examples
p1.remap_hdl_path("~/top.a1.r1");
p2.remap_hdl_path("r1");

Specman e Language Reference


1999-2015

457
.

Product Version 15.1


All Rights Reserved.

Parameters
port-exp

An expression of a port type.

new-hdl-path

The path to the new external object, enclosed in double quotes.

Description
To access an external, simulated object, you must provide a path to the object with the hdl_path()
attribute. The remap_hdl_path() pseudo-method lets you change the value of the HDL path.
Note

The remap_hdl_path() pseudo-method can be called only during the connect_ports phase.

Defining the HDL Path


If you start the HDL path with ~/, the path is treated as the absolute HDL path of the port. If you do
not start the HDL path with ~/, then the path is a concatenation of the partial paths you provide for the
port itself and for its enclosing units. The partial paths can contain any separator that is supported by the
adapter for the simulator you are using.

Example
unit A {
p1 : out simple_port of int is instance;
keep p1.hdl_path() == "r";
};
extend sys {
A : a is instance;
keep a.hdl_path() == "~/top.u1";
};
extend A {
connect_ports() is also {
print p1.full_hdl_path(); // will print "top.u1.r";
p1.remap_hdl_path("m1.r");
print p1.full_hdl_path(); // will print "top.u1.m1.r"
};
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

hdl_path() Port Attribute in the Specman Integrators Guide

Specman e Language Reference


1999-2015

458

Product Version 15.1


All Rights Reserved.

Canonical Naming Conventions in the Specman Integrators Guide

6.10.9

disconnect()

Purpose
Disconnect a port from its bound set

Category
Pseudo-method

Syntax
port-exp.disconnect();
Syntax Example
data_out.disconnect();

Description
Calling this pseudo-method of a port disconnects this port from the bound set it belongs to, and returns
it to its initial, dangling state. The rest of the bound set remains intact.

Notes

The disconnect() method can only be called during the connect_ports() sub-phase. Calling it at any
other time results in an error message.
Since dangling ports result in an error at elaboration time, you should explicitly bind the port to
empty or undefined after disconnecting it with disconnect(), or bind it to another object.
If any port in the bound set is bound only to the port you disconnect, then you have effectively returned
that port to its initial dangling state also. For example, if p1 is bound only to p2 and you disconnect
p2 as follows:
p2.disconnect();

you effectively make p1 a dangling port.

Specman deals only with bound sets and ignores the order of connection. Hence, if you write:
do_bind(p1, p2); do_bind(p2, p3); p2.disconnnect();

Specman e Language Reference


1999-2015

459
.

Product Version 15.1


All Rights Reserved.

p1 and p3 are still connected. After the second do_bind(), the bound set contained p1, p2 and p3.
p2.disconnect() just removed p2 from the bound set.

Example
unit bfm_u {
data_in: in simple_port of uint is instance;
};
extend sys {
bfm: bfm_u is instance;
data_out: out simple_port of uint is instance;
connect_ports() is {
data_out.disconnect();
do_bind(data_out, bfm.data_in);
};
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

disconnect_bound_set() on page 460

6.10.10 disconnect_bound_set()
Purpose
Disconnect all ports in the bound set of a port

Category
Pseudo-method

Syntax
port-exp.disconnect_bound_set();
Syntax Example
data_out.disconnect_bound_set();

Specman e Language Reference


1999-2015

460

Product Version 15.1


All Rights Reserved.

Description
Calling this pseudo-routine of a port disconnects all the ports in the bound set of this port, and sets the
status of all of them to be dangling.
This is logically implemented in Specman as follows:
var ports: list of any_port = port.get_bound_set();
for each (p) in ports do {
p.disconnect();
};

Note

The disconnect_bound_set() method can only be called during the connect_ports() sub-phase.
Calling it at any other time results in an error message.

Example
connect_ports() is {
data_out.disconnect_bound_set();
do_bind(data_out, bfm.data_in);
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

disconnect() on page 459

get_bound_set() on page 461

6.10.11 get_bound_set()
Purpose
Returns the bound set of a port

Category
Pseudo-method

Specman e Language Reference


1999-2015

461
.

Product Version 15.1


All Rights Reserved.

Syntax
port-exp.get_bound_set(): list of any_port
Syntax Example
var ports: list of any_port = data_out.get_bound_set();

Description
Returns the set of ports connected to that port, including itself.
Calling get_bound_set() on a disconnected port returns only the port itself.

Note

The get_bound_set() method can be called at any time, not just during the connect_ports()
sub-phase.

Example
connect_ports() is {
var ports: list of any_port = data_out.get_bound_set();
if (!ports.has(it == bfm.data_in)) then {
do_bind(data_out, bfm.data_in);
};
};

Example 4
cmd-prompt> print p2.get_bound_set()

See Also

Querying the State of Port Bindings in Creating e Testbenches

is_connected() on page 463

bind() on page 441

Specman e Language Reference


1999-2015

462

Product Version 15.1


All Rights Reserved.

6.10.12 is_connected()
Purpose
Returns TRUE if a port is a member of a bound set

Category
Pseudo-method

Syntax
port-exp.is_connected();
Syntax Example
if (!data_out.is_connected()) then {
do_bind(data_out, bfm.data_in);
};

Description
Returns TRUE if the port is connected to another port or to external.

Note

is_connected() can be called at any time, not just during the connect_ports() sub-phase.

Example 1
connect_ports() is also {
if (!data_out.is_connected()) then {
do_bind(data_out, bfm.data_in);
};
};

Example 2
cmd-prompt> print p2.is_connected()

Specman e Language Reference


1999-2015

463
.

Product Version 15.1


All Rights Reserved.

See Also

Querying the State of Port Bindings in Creating e Testbenches

get_bound_set() on page 461

bind() on page 441

6.10.13 The connect_pointers() Method of sys


Purpose
Connect unit references (pointers)

Category
Predefined method for sys

Syntax
[sys.]connect_pointers()
Syntax Example
connect_pointers() is also {
bfm.driver = driver;
driver.bfm = bfm;
};

Description
When you issue a test, start, or generate command from the Specman command line, after the unit tree
is generated and calls to post_generate() are complete, the sys.connect_pointers() method is called.
Then, every unit under sys is processed in depth-first field order and its connect_pointers() method
called before proceeding to the next unit instance. As shown in the example below, this means that the
child of a node is visited before the sibling of that node. As a result, code in lower-level units can depend
on pointers defined in higher-level units.

Specman e Language Reference


1999-2015

464

Product Version 15.1


All Rights Reserved.

Example
This example shows that the connect_pointers() method of the top-level unit, u_instance, is called
first. Then the connect_pointers() methods of the u1_instance and its child, u3_instance, are called,
because u1_instance is instantiated in u_instance before u2_instance. Finally, the connect_pointers()
methods of the u2_instance and its child, u4_instance, are called.
<'
unit u3 {
connect_pointers() is {
out("===>in connect_pointers of u3");
};
};
unit u4 {
connect_pointers() is {
out("===>in connect_pointers of u4");
};
};
unit u1 {
u3_instance: u3 is instance;
connect_pointers() is {
out("===>in connect_pointers of u1");
};
};
unit u2 {
u4_instance: u4 is instance;
connect_pointers() is {
out("===>in connect_pointers of u2");
};
};
unit u {
u1_instance: u1 is instance;
u2_instance: u2 is instance;
connect_pointers() is {
out("===>in connect_pointers of u");
};
};
extend sys {
u_instance: u is instance;

Specman e Language Reference


1999-2015

465
.

Product Version 15.1


All Rights Reserved.

};
'>
cmd-prompt > test
Doing setup ...
Generating the test using seed 1...
===>in connect_pointers of u
===>in connect_pointers of u1
===>in connect_pointers of u3
===>in connect_pointers of u2
===>in connect_pointers of u4
Starting the test ...
Running the test ...
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

(See Figure 23-1 on page 1142 for more information on test phases.)

Suggested Use
You can extend this method to set unit references procedurally. You must mark all unit pointers that are
set procedurally with a !. Failing to do so (and not constraining them either) results in a
generation-time error message:
Cannot generate xxx - not an instance

Notes

Because connect_pointers() is called after the unit tree for the VE is generated and after
post_generate() is called, any reference assigned in connect_pointers() must not be used in
constraints or in post_generate(). In general, connect_pointers() is recommended only to create
cross references between sibling units. See Propagating Data when Generating the VE in the Specman
Generation User Guide for more information.
It is not recommended to modify unit pointers after the generation phase.
To set values that depend on unit pointers, use sys.connect_ports() method or the connect_ports()
method of any unit.

See Unit Hierarchical References on page 269 for more information.

Example
unit my_sequence_driver_u {
Specman e Language Reference
1999-2015

466

Product Version 15.1


All Rights Reserved.

!bfm: my_bfm_u;
};
unit my_bfm_u {
!driver: my_sequence_driver_u;
};
extend sys {
driver: my_sequence_driver_u is instance;
bfm: my_bfm_u is instance;
connect_pointers() is also {
bfm.driver = driver;
driver.bfm = bfm;
};
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

The connect_ports() Method of sys on page 467

6.10.14 The connect_ports() Method of sys


Purpose
Connect ports procedurally and set final values that depend on unit pointers

Category
Predefined method for sys

Syntax
[sys.]connect_ports()
Syntax Example
connect_ports() is also {
do_bind(driver.data_out, bfm.data_in);
};

Specman e Language Reference


1999-2015

467
.

Product Version 15.1


All Rights Reserved.

Description
When you issue a test, start, or generate command from the Specman command line, after the unit tree
is generated and calls to connect_pointers() are complete, the sys.connect_ports() method is called.
Then, every unit under sys is processed in depth-first field order and its connect_ports() method called
before proceeding to the next unit instance. See The connect_pointers() Method of sys on page 464
for more information on depth-first order. See Figure 23-1 on page 1142 for more information on test
phases.

Suggested Use
You can extend this method to connect ports procedurally and to set final values that depend on unit
pointers.

Example
In the following example, connect_ports() calls do_bind(). The parameters of the do_bind() routine
are pointers set during the connect_pointers sub-phase of generation. This is a typical use of do_bind().
unit my_sequence_driver_u {
!bfm: my_bfm_u;
data_out: out buffer_port of uint is instance;
keep data_out.buffer_size() == 20;
};
unit my_bfm_u {
!driver: my_sequence_driver_u;
data_in: in buffer_port of uint is instance;
};
extend sys {
driver: my_sequence_driver_u is instance;
bfm: my_bfm_u is instance;
connect_pointers() is also {
bfm.driver = driver;
driver.bfm = bfm;
};
connect_ports() is also {
do_bind(driver.bfm.data_in, bfm.driver.data_out);
};
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

Specman e Language Reference


1999-2015

468

Product Version 15.1


All Rights Reserved.

connect_pointers() on page 445

do_bind() on page 449

6.10.15 The check_generation() Method of sys


Purpose
Implement user-defined checks, including connection checks

Category
Predefined method for sys

Syntax
[sys.]check_generation()
Syntax Example
check_generation() is also {
assert bind(external_clk,external);
};

Description
When you issue a test, start, or generate command from the Specman command line, after the unit tree
is generated and calls to connect_ports() are complete, the sys.check_generation() method is called.
Then, every unit under sys is processed in depth-first field order and its check_generation() method
called before proceeding to the next unit instance. See The connect_pointers() Method of sys on page
464 for more information on depth-first order. See Figure 23-1 on page 1142 for more information on
test phases.

Suggested Use
You can extend this method to implement user-defined checks, such as port binding or final value
checks.

Example
unit my_sequence_driver_u {

Specman e Language Reference


1999-2015

469
.

Product Version 15.1


All Rights Reserved.

!bfm: my_bfm_u;
data_out: out buffer_port of uint is instance;
keep data_out.buffer_size() == 20;
};
unit my_bfm_u {
!driver: my_sequence_driver_u;
data_in: in buffer_port of uint is instance;
};
extend sys {
driver: my_sequence_driver_u is instance;
bfm: my_bfm_u is instance;
connect_pointers() is also {
bfm.driver = driver;
driver.bfm = bfm;
};
connect_ports() is also {
do_bind(driver.bfm.data_in, bfm.driver.data_out);
};
check_generation() is also {
assert bind(driver.bfm.data_in, bfm.driver.data_out);
};
};

See Also

Binding Ports to External Objects or Other e Ports in Creating e Testbenches

check_generation() on page 448

6.11 Port-Related Routines

get_hdl_size() on page 470

simulator.get_hdl_path_size() on page 472

simulator.path_exists() on page 473

6.11.1

get_hdl_size()

Purpose
Returns the size of the HDL object bound to a port.

Specman e Language Reference


1999-2015

470

Product Version 15.1


All Rights Reserved.

Category
Predefined routine

Syntax
port-exp.get_hdl_size()
Syntax Example
print low4.get_hdl_size();

Parameter
port-exp

An expression that returns a simple port instance.

Description
This routine returns the size of the HDL object bound to a port (the size is in bits).
Notes

This routine applies for Verilog, VHDL, and SystemVerilog only.

If hdl_expression() is defined for the port, this routine returns the declared_range value.

If verilog_wire() is defined for the port, this method returns the declared_range value.

Example
Verilog code:
module top();
reg r1[7:0];
endmodule

e code:
unit verifier {
low4 : in simple_port of uint is instance;
keep low4.hdl_path() == "r1";
print_some_info() is also {
print low4.get_hdl_size(); // will print 8
};
};

Specman e Language Reference


1999-2015

471
.

Product Version 15.1


All Rights Reserved.

6.11.2

simulator.get_hdl_path_size()

Purpose
Returns the size of a given HDL path.

Category
Predefined routine

Syntax
simulator.get_hdl_path_size(agent, path)
Syntax Example
print simulator.get_hdl_path_size("verilog", "top.r1");

Parameter
agent

The simulator agent name, as described in the agent() unit attribute.

path

The full HDL path to the signal.

Description
This routine returns the size of a given valid HDL path. The size is given in bits.
Note

This routine applies for Verilog, VHDL, and SystemVerilog only

Example
Verilog code:
module top();
reg r1[7:0];
endmodule

e code:
extend sys {
print_signals_size() is also {
print simulator.get_hdl_path_size("verilog", "top.r1");
// will print 8
Specman e Language Reference
1999-2015

472

Product Version 15.1


All Rights Reserved.

};
};

6.11.3

simulator.path_exists()

Purpose
Returns TRUE if the given path exists for the given agent name.

Category
Predefined routine

Syntax
simulator.path_exists(agent, path)
Syntax Example
extend sys {
print_signals() is also {
if (simulator.path_exists("verilog", "top.r1")) {
out("signal top.r1 exists");
};
};
};

Parameter
agent

The simulator agent name, as described in the agent() unit attribute.

path

The full HDL path to the signal.

Description
This routine returns TRUE if the given HDL path exists or FALSE if it does not exist.
Note

This routine applies for Verilog, VHDL, and SystemVerilog only.

Example
Verilog code:

Specman e Language Reference


1999-2015

473
.

Product Version 15.1


All Rights Reserved.

module top();
reg r1[7:0];
endmodule

e code:
extend sys {
print_signals() is also {
if (simulator.path_exists("verilog", "top.r1")) {
out("signal top.r1 exists");
};
};
};

6.12 e TLM Interface Port Declaration and Access


Operator
This section contains the following:

interface_port on page 474

tlm-interface-port$.tlm-method on page 477

6.12.1

interface_port

Purpose
Transfer transactions between e units or with an external component

Category
Unit member

Syntax
port-instance-name : [list of] [direction] interface_port of tlm-intf-type
[using prefix=prefix | using suffix=suffix] [is instance]

UVM Style Syntax


Instead of direction interface_port of, use:
Specman e Language Reference
1999-2015

474

Product Version 15.1


All Rights Reserved.

interface_port ofOutput interface port


interface_imp ofInput interface port
interface_export ofExport interface port
Syntax Examples
e_packet : in interface_port of tlm_put of packet is instance;
e_packte : interface_imp of tlm_put of packet is instance;
p1 : out interface_port of tlm_nonblocking_transport of (packet, msg) \
is instance;
p1 : interface_port of tlm_nonblocking_transport of (packet, msg) \
is instance;

Parameters
port-instance-name

A unique e identifier used to refer to the port or access its value.

direction

in, out, or export. There is no default.


Note

tlm-intf-type

using suffix=suffix

interface_port ofSpecifies an output interface port


interface_imp ofSpecifies an input interface port
interface_export ofSpecifies an export interface port

The full syntax for one of the TLM interfaces listed in Supported TLM Interfaces
for e Interface Ports in the Specman Integrators Guide.

using prefix=prefix

Instead of specifying the direction, you can use UVM style syntax:

For internal e TLM interface ports, the type (or types) you specify for the
interface can be any legal e type.
External e TLM interface ports support transactions of a struct (or class) type
only. Thus, for externally bound e TLM interface ports, the type (or types)
you specify for the interface must be legal e types that inherit from any_struct.

Applies for e TLM input ports only. Specifies a prefix or suffix string to be
attached to the predefined TLM methods for the given port.
Using a prefix or suffix lets you avoid method name collisions if you define
multiple input ports under the same unit tied to the same TLM interface. Defining
a prefix or suffix to be attached to the predefined TLM method names for a given
port means that the method names for each port can be distinct.
(This syntax can be used only for the port instance members. It cannot be used in
other declarations, such as declarations for parameters or variables.)

Specman e Language Reference


1999-2015

475
.

Product Version 15.1


All Rights Reserved.

is instance

is instance denotes a physical instance of the port as a hierarchical child of the


instantiating unit. Without is instance, the declaration denotes a variable to be
used as a reference (to an instance defined elsewhere).

Description
An e TLM interface port type is parameterized with a specific TLM interface type. For example, if you
define an e TLM interface port with the syntax interface_port of tlm_nonblocking_put, you have tied
that port to the tlm_nonblocking_put interface. You can then use the set of methods (functions)
predefined for that interface to exchange transactions.

An external TLM interface output port in e is functionally equivalent to a SystemVerilog interface


port.

An external TLM input port in e is functionally equivalent to a SystemVerilog imp.

An export TLM interface port in e is functionally equivalent to a SystemVerilog TLM export.

Defining Input e TLM interface ports


When a unit contains an instance member of an input TLM interface port, the unit must implement all
methods required by the TLM interface type of that input port. The list of methods is predefined
according to the standard TLM specification.
These methods must be defined before the port is defined. (If the methods and port are defined in the
same module, the order does not matter.) If any of the required methods is missing, a compile time error
is issued.
In following example, the unit server implements the four methods/tasks which are required by the
interface tlm_put of packet.
struct packet {
...
};
unit server {
// The following four lines define the four methods required
// by the TLM interface tlm_put.
put(value : packet)@sys.any is {...};
try_put(value: packet) : bool is {...};
can_put() : bool is {...};
ok_to_put() : tlm_event is {...};
packet_in : in interface_port of tlm_put of packet is instance;
};

Specman e Language Reference


1999-2015

476

Product Version 15.1


All Rights Reserved.

If you define multiple input ports (under one unit) tied to the same TLM interface, you can avoid method
name collision by defining a string to be prefixed or suffixed to the method names for a given port
instance. This step ensures that the set of method names for each port differ from one another.
For example, the following interface_port declarations are attached to the same TLM interface, tlm_put.
However, the names of the methods for the second port will start with data_. This example allows the
two ports to both implement the same TLM methods, which would be illegal in e if the methods had the
same name.
in interface_port of tlm_put of packet is instance;
in interface_port of tlm_put of data using prefix=data_ is instance;

Limitations for Mixed Language TLM interface ports


Mixed language TLM interface ports are supported with the following list of limitations:

External e TLM interface ports are supported for IES only, not for third-party simulators.

Transactions are passed as a copy. Passing of transactions by reference is not supported.

Only transactions of a struct (or class) type are supported. This means that the element type in e must
be a legal e type that inherits from any_struct.

Note You can use the mltypemap utility to automatically map data types in e to data types in other
languages. These data types can be used as data types in ML UVM transactions using TLM ports. For
more information, see the mltypemap Utility chapter in the UVM Multi-Language Reference manual,
available in the Incisive Verification Kits with Methodology documentation.

See Also

e TLM Interface Port Binding Declarations and Methods on page 479

For more examples illustrating how to define e TLM interface ports, see connect() for e TLM Interface
Ports on page 479.

6.12.2

tlm-interface-port$.tlm-method

Purpose
Call a TLM interface method with an output e TLM interface port

Category
Operator
Specman e Language Reference
1999-2015

477
.

Product Version 15.1


All Rights Reserved.

Syntax
tlm-interface-output-port-exp$.tlm-method
Syntax Example
p$.put(my_packet);

Parameters
tlm-interface-output-port-exp An expression that returns an output e TLM interface port instance.
tlm-method

A method of a TLM interface that is supported for e TLM interface ports.

Description
The $ access operator is used to call a TLM method with an output e TLM interface port. If you attempt
to call the method via the port without the $ operator a syntax error is issued.
Without the $ operator an expression of any type port refers to the port itself, not to its value. In
particular, an expression without the $ operator can be used for operations involving port references.
Note You cannot apply the $ access operator to an item of type any_interface_port. Abstract types
do not have any access methods.

Example
struct packet {
...
};
unit client {
p : out interface_port of tlm_put of packet;
verify()@sys.any is {
var my_packet : packet;
gen my_packet;
p$.put(my_packet);
};
};

See Also

Using e TLM interface ports in the Specman Integrators Guide

Specman e Language Reference


1999-2015

478

Product Version 15.1


All Rights Reserved.

6.13 e TLM Interface Port Binding Declarations and


Methods
This section contains the following:

connect() for e TLM Interface Ports on page 479

remap_external_uvm_path() on page 483

Methods for Getting Bound Sets for e TLM Interface Ports on page 484

6.13.1

connect() for e TLM Interface Ports

Purpose
Create an outbound connection from an e TLM interface port

Category
e TLM interface port pseudo-method

Syntax
port1-exp.connect(port2-exp)
port1-exp.connect(empty | undefined)
port1-exp.connect(external_uvm_path)

Syntax Examples
env.agent[1].my_port.connect(env.agent[2].my_export)
env.agent.monitor.port.connect(empty);

Parameters
port-exp1

An e TLM interface output or export port expression (not of type


any_interface_port).
port-exp1 cannot be an input port.

Specman e Language Reference


1999-2015

479
.

Product Version 15.1


All Rights Reserved.

port-exp2

An e TLM interface port expression of any direction (output, input, or


export). port-exp2 cannot of type any_interface_port.

empty

port-exp2 must have the same transaction type as port-exp1.


The interface of port-exp2 must be a superset of the interface of
port-exp1.

Defines a disconnected e TLM output interface port. In this case,


invoking a method on port-exp1 is like calling an empty port.
When port-exp1 is bound to empty, this must be the only outbound
connection it has.

undefined

Defines a disconnected e TLM output interface port. In this case,


invoking a method on port-exp1 causes a run-time error.
When port-exp1 is bound to undefined, this must be the only outbound
connection it has.

external-uvm-path

Path to a specific external UVM port, of any direction.

Description
This method creates an outbound connection from port-exp1. The connect() method can be called only
during the connect_ports() phase.
Note When used with interface ports or TLM 2.0 sockets, connect() is supported for e2e and external
ports whereas, when used with method ports, connect() is supported for e2e ports only.

Connecting Output Interface Ports


If port-exp1 is an output port, it can be connected to:

Another e TLM interface output port, and e export port, or an e input port.

A specific external UVM port of any direction.

empty or undefined.

Note For output ports, you can either use connect() or external_uvm_path() to bind port-exp1 to
external and identify the external UVM path.

Specman e Language Reference


1999-2015

480

Product Version 15.1


All Rights Reserved.

Connecting Export Interface Ports


An export interface port is like an export TLM port in SystemVerilog-UVM: its enclosing unit does
implement the required interface methods, but rather passes that task on via the chain of connected ports.
An export interface port must be connected, directly or indirectly, to an input interface port or an
external port that implements the interface methods.
If port-exp1 is an export port, it can be connected to:

Another e TLM interface export port or an e input port.

A specific external UVM port that is either input or export.

An export port must be connected using the connect() method. The bind() constraints and the
do_bind() routine are not applicable for an export interface port.
Note Because export ports are always connected with the connect() method, the port attribute
external_uvm_path() does not apply for these ports.
The following figure illustrates hierarchical binding between e and SystemVerilog, with chaining of
TLM interface ports/exports between the actual port/implementation pairs.
e

Note

SystemVerilog

interface_port

port

interface_export

export

interface_imp

imp

This type of hierarchical binding across the language border is not supported for e / SystemC.

Connecting Analysis Broadcast Ports


If port-exp1 is an analysis port (an e TLM interface port implementing the tlm_analysis interface),
multiple binding is supported for e /SystemVerilog:

Multiple e analysis exports (imp) can be connected to a single SystemVerilog analysis port.

. Similarly, multiple SystemVerilog analysis ports can be connected to a single e analysis export (imp).

Specman e Language Reference


1999-2015

481
.

Product Version 15.1


All Rights Reserved.

Example 1 Connecting an Export Interface Port


In this example, the unit agent has an input interface port impl1 and it implements the
tlm_nonblocking_put interface. The unit env defines an export exp1. There is a hierarchical connection
from exp1 to impl1.
unit agent {
impl1 : in interface_port of tlm_nonblocking_put of packet is instance;
try_put(p:packet) : bool is { };
can_put() : bool is { };
ok_to_put() : tlm_event is { };
};
unit env {
a : agent is instance;
exp1 : export interface_port of tlm_nonblocking_put of packet is
instance;
connect_ports() is also {
exp1.connect(a.impl1);
};
};

Example 2 Connecting an Analysis Port for Broadcasting


The monitor unit defines a TLM analysis port. The port is then connected to four implementers: two in
e and two external.
unit monitor {
my_port : out interface_port of tlm_analysis of packet is instance;
sample_item()@sys.any is {
var p : packet;
// read packet from DUT and fill packet
p.data = ;
my_port$.write(p);
};
};
unit scoreboard {
my_imp : in interface_port of tlm_analysis of packet is instance;
write(p:packet) is {
// do something with p
};
};
unit checker {
my_imp : in interface_port of tlm_analysis of packet is instance;
write(p:packet) is {
// do something with p
};
Specman e Language Reference
1999-2015

482

Product Version 15.1


All Rights Reserved.

};
extend sys {
m : monitor is instance;
c : checker is instance;
s : scoreboard is instance;
connect_ports() is also {
m.my_port.connect(c.my_imp);
m.my_port.connect(s.my_imp);
m.my_port.connect(uvm_top.c.my_imp); // external connection
m.my_port.connect(uvm_top.s.my_imp); // external connection
};
};

See Also

Binding e TLM interface ports in the Specman Integrators Guide

6.13.2

remap_external_uvm_path()

Purpose
Change the external UVM TLM interface port to which an e TLM interface port instance is connected

Category
Port pseudo-method

Syntax
e-TLM-interface-port-exp.remap_external_uvm_path(external_uvm_path);
Syntax Example
client.nb_put.remap_external_uvm_path("uvm_test_top.top+env.monitor.nb_in");

Parameters
e-TLM-interface-port-exp An expression of an e TLM interface port.

Specman e Language Reference


1999-2015

483
.

Product Version 15.1


All Rights Reserved.

external_uvm_path

The path to the new external UVM TLM interface port, in double quotes.
The external port can be of any direction.
The path can be a partial path. Specman concatenates the partial paths you
provide for the port and its enclosing units.

Description
To access an external UVM TLM interface port, you must provide a path to the port instance with the
external_uvm_path() attribute. The remap_external_uvm_path() pseudo-method lets you change the
external UVM TLM interface port.
Notes

The legacy pseudo-method remap_external_ovm_path is also supported, but might be deprecated


in the future. The config -sim -target_ml_lib command determines whether Specman generates
UVM or OVM compliant code. The default is UVM.
The remap_external_uvm_path() pseudo-method can be called only during the connect_ports
phase.

See Also

e TLM Interface Port Attribute in the Specman Integrators Guide

6.13.3

Methods for Getting Bound Sets for e TLM Interface


Ports

Table 6-1 on page 485 describes the methods you can use to get bound sets for e TLM Interface ports.

Direct Versus Indirect Connections


In directed binding, the connections have direction. If port1 is connected to port2, then port1 has
outbound connection to port2 and port2 has inbound connection from port1. In this case, port1 is
directly connected to port2. If port1 is connected to port2, and port2 is connected to port3, then port1
and port3 are indirectly connected.

Specman e Language Reference


1999-2015

484

Product Version 15.1


All Rights Reserved.

Method Descriptions
Table 6-1

e TLM Interface Port Methods

port-exp.get_outbound_set()
port-exp.get_inbound_set()

These two methods return the set of all the e2e ports to
which the specified e TLM interface port has:

port-exp.get_direct_outbound_set()
port-exp.get_direct_inbound_set()

These two methods return the set of all the e2e ports to
which the specified e TLM interface port has:

port-exp.get_outbound_external_set()
port-exp.get_inbound_external_set()

Direct outbound connections


Direct inbound connections.

These two methods return the set of all external port


paths to which the specified e TLM interface port has:

port-exp.print_hierarchical_bindings()

Direct or indirect outbound connections


Direct or indirect inbound connections.

Direct outbound connections


Direct inbound connections.

This method prints the connection network starting from


the specified e TLM interface port.
This method also prints the complete direct inbound set
of ports (external and e2e) connected to the specified e
TLM interface port.

Example
unit client1 {
out1 : out interface_port of tlm_analysis of (packet) is instance;
keep bind(out1,external);
connect_ports() is also {
out1.connect("test.top_env.server3.imp3");
out1.connect("test.top_env.server2.imp2");
ml_uvm.connect_names(out1.e_path(),"test.top_env.server1.imp1");
ml_uvm.connect_names("test.top_env.client.out_port",out1.e_path()
);
};
run() is also {
var outbound_paths := out1.get_outbound_external_set();
for each in outbound_paths do {
out("out1 is connected to ",it);
Specman e Language Reference
1999-2015

485
.

Product Version 15.1


All Rights Reserved.

};
var inbound_paths := out1.get_inbound_external_set();
for each in inbound_paths do {
outf("%s is connected to out1\n",it);
};
};

};
extend sys {
client1 is instance;
};

The output for this example is:


out1 is connected to test.top_env.server1.imp1
out1 is connected to test.top_env.server2.imp2
out1 is connected to test.top_env.server3.imp3
test.top_env.client.out_port is connected to out1

Note

The print_hierarchical_binding() method would also provide this information.

6.14 e TLM 2.0 Socket Declaration and Predefined


Methods
This section contains the following:

tlm_initiator_socket / tlm_target_socket on page 486

b_transport() on page 489

nb_transport_fw() on page 493

nb_transport_bw() on page 497

transport_dbg() on page 500

set_bus_width() on page 502

get_bus_width() on page 503

6.14.1

tlm_initiator_socket / tlm_target_socket

Purpose
Provide the interface for accessing external and internal TLM 2.0 sockets.

Specman e Language Reference


1999-2015

486

Product Version 15.1


All Rights Reserved.

Category
Unit member

Syntax
tlm_socket_instance: [list of] tlm-socket-type [of type]
[using prefix=prefix | using suffix=suffix] [is instance];
Syntax Example
unit simple_driver like uvm_bfm {
driver_i_socket: tlm_initiator_socket using prefix = "my" is instance;
};

Parameters
tlm_socket_instance

The e name for this socket instance.

tlm-socket-type

Defines the socket as an initiator socket or a target socket. Legal


values:

tlm_initiator_socket
tlm_target_socket

of type

Currently, the only type supported is tlm_generic_payload (the


default). Therefore, there is no need to include this parameter.

using prefix=prefix

By default, instantiation of multiple TLM 2.0 sockets in the same


unit type results in all sockets using the same predefined
methodsbecause the method names are the same for each socket.

using suffix=suffix

To implement a different set of method names for each socket


instance, you define a prefix or suffix with using prefix or using
suffix. The prefix or suffix you define is attached to all the method
names for the current socket instantiation, thus creating a unique set
of methods.
The prefix or suffix must be a string type. (Note that the text for a
string type is always enclosed with double quotation marks.)
is instance

is instance denotes a physical instance of the socket as a hierarchical


child of the instantiating unit. Without is instance, the declaration
denotes a variable to be used as a reference (to an instance defined
elsewhere).

Specman e Language Reference


1999-2015

487
.

Product Version 15.1


All Rights Reserved.

Description
The tlm_initiator_socket/tlm_target_socket declaration defines and instantiates e TLM 2.0 sockets.
Every transaction requires both an initiator socket and a target socket.
You must instantiate e TLM 2.0 sockets in units, where you also implement the socket predefined
methods b_transport(), nb_transport_fw(), and nb_transport_bw().
Note The TLM 2.0 socket base type any_tlm_socket is derived from the any_port base type. Thus,
TLM 2.0 sockets have the same basic facilities as other e ports. (For an overall description of using e
ports, see Creating e Ports in Creating e Testbenches.)

Example
This example illustrates the use of prefixes and suffixes.
unit verifier {
initiator1: tlm_initiator_socket of tlm_generic_payload using
prefix=my is instance;
initiator2: tlm_initiator_socket of tlm_generic_payload using
suffix=cb is instance;
// initiator 1 interface method implementation
my_nb_transport_bw(trans: tlm_generic_payload, phase:
*tlm_phase_enum,t: *time) : tlm_sync_enum is {
...
};
// initiator 2 calllback
nb_transport_bw_cb(trans: tlm_generic_payload, phase:
*tlm_phase_enum,t: *time) : tlm_sync_enum is {
...
};
};

See Also

b_transport() on page 489

nb_transport_fw() on page 493

nb_transport_bw() on page 497

Using e TLM 2.0 Sockets in the Specman Integrators Guide

Multi-Language TLM 2.0 in the UVM Multi-Language Reference Manual

Specman e Language Reference


1999-2015

488

Product Version 15.1


All Rights Reserved.

6.14.2

b_transport()

Purpose
The blocking transport interface is appropriate for completing a transaction with a target during the
course of a single function call, the only timing points of interest being those that mark the start and the
end of the transaction.

Category
Predefined TCM of e TLM 2.0 sockets

Syntax
b_transport(trans: tlm_generic_payload, time: *time)@sys.any
Syntax Example
b_transport(tr: tlm_generic_payload, t: *time) @sys.any is {
wait delay(t);
tr.m_response_status = execute_transaction(tr);
t = t+ latency;
};

Parameters
trans

The transaction type declared for the payload, of type tlm_generic_payload or of a struct
type derived from tlm_generic_payload with like inheritance.

time

Time delay from current simulation time, indicating when the transaction is to be processed.
Must be of type time.
Note The time parameter is a reference parameter, as designated by the asterisk (*). This
enables the method, when called, to update the time value.
For more information, see b_transport() and Timing Delays.

Description
The b_transport() TCM is used to transport a TLM 2.0 payload to target sockets in blocking mode.

Specman e Language Reference


1999-2015

489
.

Product Version 15.1


All Rights Reserved.

When the b_transport() TCM of the initiator socket is called, the initiator socket passes it to the
connected target socket.The target socket completes the transaction by returning the payload that has
been read or modified by the user-defined implementation of b_transport() on the target socket side.
The only timing points of interest are those that mark the start and the end of the transaction.
Once the b_transport() TCM returns, the transaction has been completed by the target.The
response_status field of the transaction payload that is returned by the target indicates success or
failure.

Implementing b_transport() in the Target Socket


You must implement (define the contents of) b_transport() for all target sockets that you declare,
regardless of whether it is used or not.
When you implement this method for a target socket, you must provide the full syntax, as you would for
any regular method and as illustrated in the following example.
unit memory {
tsocket: tlm_target_socket of tlm_generic_payload is instance;
ram : simple_ram_env_u is instance;
b_transport(tr: tlm_generic_payload, t: *time) @sys.any is {
wait delay(t);
tr.m_response_status = execute_transaction(tr);
t = t+ latency;
};
execute_transaction(tr: tlm_generic_payload):tlm_response_status is {
// implement interface to memory
};
};

Notes

You must implement b_transport() in the unit where the target socket is instantiated.
You must set the target-socket payload response_status field to a tlm_response_status value before
returning the payload in response to a b_transport() call. For more information, see
tlm_response_status on page 512.
If the target socket is declared with a prefix or suffix, the prefix or suffix string is added to b_transport
as part of the method name. For example, if the prefix string is my_, then the name of the method
is my_b_transport(). For more information, see tlm_initiator_socket / tlm_target_socket on page
486.
You must implement b_transport() before the socket is used. (If the socket and the socket methods
are defined in the same module, the order does not matter.).
If a target socket does not implement b_transport(), a load error occurs.

Specman e Language Reference


1999-2015

490

Product Version 15.1


All Rights Reserved.

Invoking b_transport() from the Initiator Socket


To invoke b_transport():

Use the $ access operator.

The following e code generates a generic payload item and then invokes b_transport() to drive it to the
target socket:
pull_and_drive_items()@sequencer.clock is {
var req: tlm_generic_payload;
var resp_time : time;
while (TRUE) {
// pull a generic payload item from the sequencer
req = sequencer.get_next_item();
// drive the generic payload item to the model
driver_i_socket$.b_transport(req, resp_time );
// signal the sequencer item_done
emit sequencer.item_done;
message(LOW, "sent dummy data to SC");
};
};

b_transport() and Timing Delays


Because it is a blocking method, b_transport() is a time consuming method (TCM). This means that the
body of b_transport() can call, for example, wait to indicate a delay before transmission.
Figure 6-1 illustrates two b_transport() calls, one with a wait delay of 40ns.

Specman e Language Reference


1999-2015

491
.

Product Version 15.1


All Rights Reserved.

Figure 6-1

b_transport() Call and Return

Initiator

Target

Simulation time = 100ns

Call: b_transport(trans, 0ns);


Return: b_transport(trans, 0ns);

Call: b_transport(trans, 0ns);

wait (40ns)

Simulation time = 140ns

Return: b_transport(trans, 0ns);

b_transport() also has a time argument that can be used on both the call and the return to indicate the
time of the start or end of the transaction, respectively, relative to the current simulation time. If,
however, a wait is called in the body of the method, the time offset indicated by the time argument is
reset to 0. In Figure 6-2, the second return from the initiator happens at simulation time 140ns, but with
an annotated delay of 5ns, giving an effective local time of 145ns. (The initial 5ns and 10ns delays
included in the first call and return are reset to 0.)
Note For complete details about how the time argument is used in SystemC, see the IEEE Standard
for Standard SystemC Language Reference Manual (IEEE1666-2011).

Specman e Language Reference


1999-2015

492

Product Version 15.1


All Rights Reserved.

Figure 6-2

b_transport() Call and Return

Initiator

Target

Simulation time = 100ns

Call: b_transport(trans, 5ns);


+5ns
+10ns

Return: b_transport(trans, 10ns);

Call: b_transport(trans, 0ns);

wait (40ns)

Simulation time = 140ns

+5ns

Return: b_transport(trans, 5ns);

See Also

e TLM 2.0 Socket Declaration and Predefined Methods on page 486

Using e TLM 2.0 Sockets in the Specman Integrators Guide

Multi-Language TLM 2.0 in the UVM Multi-Language Reference Manual

6.14.3

nb_transport_fw()

Purpose
Sends a transaction on the forward path (from the initiator socket to the target socket).

Category
Predefined method of e TLM 2.0 sockets
Specman e Language Reference
1999-2015

493
.

Product Version 15.1


All Rights Reserved.

Syntax
nb_transport_fw(trans: tlm_generic_payload, phase: *tlm_phase_enum, time: *time): tlm_sync_enum
Syntax Example
var status := i_socket$.nb_transport_fw(req, ph, t);

Parameters
trans

The transaction type declared for the payload, of type tlm_generic_payload or of a


struct type derived from tlm_generic_payload with like inheritance.

phase

The phase for the transaction, of type tlm_phase_enum. Passed by reference (as
indicated by the asterisk).

time

Time delay from current simulation time, indicating when the transaction is to be
processed. Must be of type time. Passed by reference (as indicated by the asterisk).
Note Because nb_transport_fw() is a non-time-consuming method, it cannot
implement a delay. If a delay is indicated, you must start a TCM from this method to
implement the delay. (See The time Argument for nb_transport_fw() on page 496
below.)

tlm_sync_enum

nb_transport_fw() returns a value of tlm_sync_enum on page 514.

Description
The nb_transport_fw() method is used to transport a transaction to target sockets in non-blocking
mode. When the nb_transport() method of the initiator socket is called, the initiator socket passes it to
the connected target socket. nb_transport() returns the status of the transaction, as a tlm_sync_enum
type.
nb_transport_fw() is one of two non-blocking transport methods:

nb_transport_fw() is used for the forward path.

nb_transport_bw() on page 497 is used for the backward path.

The non-blocking transport interface is intended to support pipelined transactions. In other words, each
successive call to nb_transport_fw() from the same process can initiate a separate transaction without
having to wait for the first transaction to complete.
Note The phase and time parameters are reference parameters, as designated by the asterisk (*). This
enables the method, when called, to update the values of those parameters.

Specman e Language Reference


1999-2015

494

Product Version 15.1


All Rights Reserved.

Phases of a Non-Blocking Transfer


The non-blocking transport interface breaks a transaction into multiple timing points with the use of
separate phases. Thus, a transaction typically requires multiple function calls for a single transaction.
The IEEE Standard for Standard SystemC Language Reference Manual (IEEE1666-2011) refers to
this mode of working as an approximately-timed coding style.

Each phase transition is associated with a timing point.


Each phase is associated with a value of tlm_phase_enum. The following tlm_phase_enum values
are supported:

BEGIN_REQbegin request; sent only via nb_transport_fw() from the initiator socket.

END_REQend request; sent only via nb_transport_bw() from the target socket.

BEGIN_RESPbegin response; sent only via nb_transport_bw() from the target socket.

END_RESPend response; sent only via nb_transport_fw() from the initiator socket.

The IEEE Standard for Standard SystemC Language Reference Manual (IEEE1666-2011), sections
4.1.2 and 8.1, describe how the phases work and how they are executed. Please read this manual for a
complete understanding of the phases.

Implementing nb_transport_fw() in a Target Socket


You must implement (define the contents of) nb_transport_fw() for all target sockets that you declare,
regardless of whether it is used or not.
When you implement this method for a target socket, you must provide the full syntax, as you would for
any regular method and as illustrated in the following example:
t_socket : tlm_target_socket is instance;
// implement nb_transport - non-blocking transaction
nb_transport_fw(tr: tlm_generic_payload, phase: *tlm_phase_enum, t: *time):
tlm_sync_enum is {
if(phase != BEGIN_REQ && phase != END_RESP) {
dut_error("SLAVE driver nb_transport_fw received phase ", phase);
};
return TLM_ACCEPTED;
}; // nb_transport_fw

Notes

You must implement nb_transport_fw() in the unit where the target socket is instantiated.

Specman e Language Reference


1999-2015

495
.

Product Version 15.1


All Rights Reserved.

If the target socket is declared with a prefix or suffix, the prefix or suffix string is added to
nb_transport_fw as part of the method name. For example, if the prefix string is my_, then the
name of the method is my_nb_transport_fw(). For more information, see tlm_initiator_socket /
tlm_target_socket on page 486

You must implement nb_transport_fw() before the socket is used. (If the socket and the socket
methods are defined in the same module, the order does not matter.) Failure to implement the required
methods or TCMs will result in load time errors.
If a target socket does not implement nb_transport_fw(), a load error occurs.

Invoking nb_transport_fw() from an Initiator Socket


To invoke nb_transport_fw():

Use the $ access operator.

The $ operator reads the tlm_sync_enum value that is returned by nb_transport_fw(). The following
example is taken from the longer example in Master Driver (BFM) Using the Initiator Socket in the UVM
Multi-Language Reference:
pull_and_drive_items() @ sequencer.clock is {
var req: tlm_generic_payload;
var t: time = 0;
var p: tlm_phase_enum;
while (TRUE) {
req = sequencer.get_next_item();
p = BEGIN_REQ;
if(i_sckt$.nb_transport_fw(req, p, t) != TLM_ACCEPTED) {
dut_error("MASTER simple_driver nb_transport_fw failed");
};
emit sequencer.item_done;
};
};

The time Argument for nb_transport_fw()


The time argument for nb_transport_fw() indicates a delay to be executed before the transaction is
processed. nb_transport_fw(), however, is a non-time-consuming method and therefore cannot
implement any delays.
To implement a delay before the transaction is processed:

Start a TCM from nb_transport_fw().

Specman e Language Reference


1999-2015

496

Product Version 15.1


All Rights Reserved.

The following code illustrates doing so using a TCM named nb_transport_fw_respond. This code is
taken from the example in Slave Driver (BFM) Using the Target Socket in the UVM Multi-Language
Reference Manual:
nb_transport_fw(tr: tlm_generic_payload, phase: *tlm_phase_enum, t: *time):\
tlm_sync_enum is {
if(phase != BEGIN_REQ && phase != END_RESP) {
dut_error("SLAVE driver nb_transport_fw received phase ", phase);
};
start nb_transport_fw_respond(tr, phase, t);
return TLM_ACCEPTED;
}; // nb_transport_fw
// Time consuming method started from non-blocking call
nb_transport_fw_respond(tr: tlm_generic_payload, phase: tlm_phase_enum,
t: time)@sys.any is {
wait delay(t); // simulate delay
...

Note For complete details about how the time argument is used in SystemC, see the IEEE Standard
for Standard SystemC Language Reference Manual (IEEE1666-2011).

See Also

e TLM 2.0 Socket Declaration and Predefined Methods on page 486

Using e TLM 2.0 Sockets in the Specman Integrators Guide

Multi-Language TLM 2.0 in the UVM Multi-Language Reference Manual

6.14.4

nb_transport_bw()

Purpose
Sends an updated transaction on the backward path (from the target socket to the initiator socket), in
non-blocking mode.

Category
Predefined method of e TLM 2.0 sockets

Syntax
nb_transport_bw(trans: tlm_generic_payload, phase: *tlm_phase_enum, time: *time) :
tlm_sync_enum
Specman e Language Reference
1999-2015

497
.

Product Version 15.1


All Rights Reserved.

Syntax Example
};

Parameters
trans

The transaction type declared for the payload, of type tlm_generic_payload or of a


struct type derived from tlm_generic_payload with like inheritance.

phase

The phase for the transaction, of type tlm_phase_enum. Passed by reference (as
indicated by the asterisk).

time

Time delay from current simulation time, indicating when the transaction is to be
processed. Must be of type time. Passed by reference (as indicated by the asterisk).
Note Because nb_transport_bw() is a non-time-consuming method, it cannot
implement a delay. If a delay is indicated, you must start a TCM from this method to
implement the delay.
See The time Argument for nb_transport_fw() on page 496 in the description of
nb_transport_fw() on page 493 for more information.

tlm_sync_enum nb_transport_fw() returns a value of tlm_sync_enum on page 514.

Description
The nb_transport_bw() method sends s transaction on the backward path (from the target socket to the
initiator socket) after it has been received via nb_transport_fw() and updated. The nb_transport_bw()
method returns the status of the transaction, as a tlm_sync_enum type.
The non-blocking transport interface is intended to support pipelined transactions. In other words, each
successive call to nb_transport_fw() from the same process can initiate a separate transaction without
having to wait for the first transaction to complete.
Please see Phases of a Non-Blocking Transfer on page 495 for a description of how the overall
non-blocking transport interface works.
Note The phase and time parameters are reference parameters, as designated by the asterisk (*). This
enables the method, when called, to update the values of those parameters.

Implementing nb_transport_bw() in an Initiator Socket


You must implement (define the contents of) nb_transport_bw() for all initiator sockets that you
declare, regardless of whether it is used or not.

Specman e Language Reference


1999-2015

498

Product Version 15.1


All Rights Reserved.

When you implement this method for an initiator socket, you must provide the full syntax, as you would
for any regular method and as illustrated in the following example. In this example,
nb_transport_bw():

Outputs a message identifying whether the executed transfer was a read or a write.
Prints the contents of the payload data (the m_data field) if this transmission from nb_transport_bw()
is the beginning of the transaction response phase.
Sets the tlm_sync_enum return value to TLM_ACCEPTED. (tlm_sync_enum is described in
Phases of a Non-Blocking Transfer on page 495.)

The following example is taken from the longer example in Master Driver (BFM) Using the Initiator
Socket in the UVM Multi-Language Reference:
nb_transport_bw(resp: tlm_generic_payload, phase: *tlm_phase_enum, t: *time): \
tlm_sync_enum is {
message(HIGH, "Response from nb_transport_bw: ", resp.m_command);
if(resp.m_command == TLM_READ_COMMAND && phase == BEGIN_RESP) {
print resp.m_data;
};
return TLM_ACCEPTED;
};

Notes

You must implement nb_transport_bw() in the unit where the initiator socket is instantiated.
If the initiator socket is declared with a prefix or suffix, the prefix or suffix string is added to
nb_transport_bw as part of the method name. For example, if the prefix string is my_, then the
name of the method is my_nb_transport_bw(). For more information, see tlm_initiator_socket /
tlm_target_socket on page 486.
You must implement nb_transport_bw() before the socket is used. (If the socket and the socket
methods are defined in the same module, the order does not matter.) Failure to implement the required
methods or TCMs will result in load time errors.
If an initiator socket does not implement nb_transport_bw(), a load error occurs.

Calling nb_transport_bw() from a Target Socket


To invoke nb_transport_bw():

Use the $ access operator.

The $ operator reads the tlm_sync_enum value that is returned by nb_transport_bw(). The following
example is taken from the longer example in Slave Driver (BFM) Using the Initiator Socket in the UVM
Multi-Language Reference.

Specman e Language Reference


1999-2015

499
.

Product Version 15.1


All Rights Reserved.

var status := t_socket$.nb_transport_bw(tr, phase, tm);


if(status != TLM_COMPLETED && status != TLM_ACCEPTED) {
dut_error("SLAVE driver nb_transport_bw received unexpected status ", status);
};

See Also

e TLM 2.0 Socket Declaration and Predefined Methods on page 486

Using e TLM 2.0 Sockets in the Specman Integrators Guide

Multi-Language TLM 2.0 in the UVM Multi-Language Reference Manual

6.14.5

transport_dbg()

Purpose
Provides debug capability by reading from or writing to memory in the target.

Category
Predefined method of e TLM 2.0 sockets

Syntax
transport_dbg(trans) : uint
Syntax Example
var len := i_socket$.transport_dbg(req);

Parameters
trans

The transaction type declared for the payload, of type tlm_generic_payload or of a struct
type derived from tlm_generic_payload with like inheritance.
The default debug transaction type uses only the following attributes of the transaction object:

command
address
data length
data pointer attributes

Specman e Language Reference


1999-2015

500

Product Version 15.1


All Rights Reserved.

uint

transport_dbg() returns the number of bytes read or written.

Description
The transport_dbg() method gives the initiator socket the ability to read from or write to memory in the
target. The intent is to provide access to the data for debug purposes.
transport_dbg() returns the number of bytes read or written. If the target is not able to perform the
operation, transport_dbg() returns a value of 0.

Implementing transport_dbg() in a Target Socket


You must implement (define the contents of) transport_dbg() for all target sockets that you declare,
regardless of whether it is used or not.
When you implement this method for a target socket, you must provide the full syntax, as you would for
any regular method and as illustrated in the following example. This example is taken from the longer
example in Slave Driver (BFM) Using the Initiator Socket in the UVM Multi-Language Reference.
transport_dbg(tr: tlm_generic_payload): uint is {
if (tr.m_command == TLM_READ_COMMAND) {
tr.m_data.clear();
for i from 0 to tr.m_length-1 {
tr.m_data.add(i%256);
};
};
return tr.m_length;
};

Notes

You must implement transport_dbg() in the unit where the target socket is instantiated.
If the target socket is declared with a prefix or suffix, the prefix or suffix string is added to
transport_dbg as part of the method name. For example, if the prefix string is my_, then the name
of the method is my_transport_dbg(). For more information, see tlm_initiator_socket /
tlm_target_socket on page 486.
You must implement transport_dbg() before the socket is used. (If the socket and the socket methods
are defined in the same module, the order does not matter.).
If a target socket does not implement transport_dbg(), a load error occurs.

Specman e Language Reference


1999-2015

501
.

Product Version 15.1


All Rights Reserved.

Calling transport_dbg() from an Initiator Socket


To invoke nb_transport_bw():

Use the $ access operator.

The following example sets the variable len to the value returned by transport_dbg(), which is the
number of bytes read or written.
var len := i_socket$.transport_dbg(req);

See Also

e TLM 2.0 Socket Declaration and Predefined Methods on page 486

Using e TLM 2.0 Sockets in the Specman Integrators Guide

Multi-Language TLM 2.0 in the UVM Multi-Language Reference Manual

6.14.6

set_bus_width()

Purpose
Sets the bus width for the current socket.

Category
Predefined method of e TLM 2.0 sockets

Syntax
set_bus_width( nn: uint )
Syntax Example
i_socket.set_bus_width(64);

Parameter
nn

The bus width to be set.

Specman e Language Reference


1999-2015

502

Product Version 15.1


All Rights Reserved.

Description
set_bus_width() sets the bus_width() socket attribute (in bits) for the current socket. The default is 32
bits.
A load time error results if the bus width is defined incorrectly for a given TLM 2.0 socket. When an
initiator socket is bound to its corresponding target socket, the bus widths for both sockets must be the
same.
Note set_bus_width() can only be used until the end of connect_ports(), because the bus width is a
static property and cannot be changed at runtime.

See Also

For more information, see bus_width in Specman Integrators Guide.

6.14.7

get_bus_width()

Purpose
Get the bus width for the current socket.

Category
Predefined method of e TLM 2.0 sockets

Syntax
get_bus_width() : uint
Syntax Example
bw: uint = i_socket.get_bus_width();

Description
Returns the bus width for this socket.

See Also

For more information, see bus_width in Specman Integrators Guide.

Specman e Language Reference


1999-2015

503
.

Product Version 15.1


All Rights Reserved.

6.15 e TLM 2.0 Predefined Structs and Enumerated


Data Types
e TLM 2.0 sockets use the following e enumerated data types. These data types are equivalent to the
SystemC data types.

tlm_command on page 504

tlm_endianness on page 505

tlm_extension on page 506

tlm_generic_payload on page 507

tlm_phase_enum on page 511

tlm_response_status on page 512

tlm_sync_enum on page 514

6.15.1

tlm_command

Purpose
Identifies the basic operation to be performed with the e TLM 2.0 payload.

Category
Enumerated type

Description
Two basic operationsread and writeare supported for the e TLM 2.0 payload transaction. In
addition, an ignore operation lets attribute values of the generic payload to be passed to the target
socket without requiring a read or write.
tlm_command identifies which operation is to be performed with the current payload transaction. The
initiator socket sets the tlm_command value for the transaction.
Possible values for this enumerated type are as follows:
type tlm_command: [TLM_READ_COMMAND,
TLM_WRITE_COMMAND,
TLM_IGNORE_COMMAND];

These values are described below.

Specman e Language Reference


1999-2015

504

Product Version 15.1


All Rights Reserved.

TLM_READ_COMMAND The target socket copies data from the specified address to the
transaction payload before passing it back to the initiator socket. (In other words, the initiator socket
reads data from the target socket.)
TLM_WRITE_COMMANDThe target socket copies data from the current transaction payload
to the specified address. (In other words, the initiator socket writes data to the target socket.)
TLM_IGNORE_COMMANDThe target socket does not perform a read or write. It can, however,
make use of the value of any attribute in the transaction payload, including extensions. The intent is
to allow the payload to act as a vehicle for transporting payload extension values.
Note An ignore command is considered successful if the target socket has received the generic
payload and checked the attribute values as per its need.

Example
The section TLM 2.0 Interface User View for e in the UVM Multi-Language Reference contains an
extended example illustrating the use of TLM 2.0 constructs in an e testbench.
For example, Data Types Definition in the UVM Multi-Language Reference includes examples of how to
generate generic payload bursts in which the values of tlm_command are used to control whether the
burst is a read or write operation.

See Also

tlm_generic_payload on page 507

e TLM 2.0 Socket Declaration and Predefined Methods on page 486

6.15.2

tlm_endianness

Purpose
Identifies the endianness value for the current payload transaction.

Category
Enumerated type

Description
All data in the tlm_generic_payload data array must take the same endianness as the DUT TLM 2.0
model. It is your responsibility to ensure that this rule is followed.

Specman e Language Reference


1999-2015

505
.

Product Version 15.1


All Rights Reserved.

You can get the endianness value for the current host by getting the current value of this enumerated type
or with the utility method get_host_endianness() (described in Utility Methods for e TLM 2.0 Sockets in
the Specman Integrators Guide.)
Possible values for this enumerated type are as follows:
type tlm_sync_enum: [TLM_UNKNOWN,
TLM_LITTLE_ENDIAN,
TLM_BIG_ENDIAN];

These values are described below:

TLM_LITTLE_ENDIAN indicates that the host is a Linux or Sol86 machine.

TLM_BIG_ENDIAN indicates that the host is a Solaris or AIX machine.

See Also

Overall Steps for Implementing TLM 2.0 Sockets in an e Testbench in the Specman Integrators Guide

6.15.3

tlm_extension

Purpose
Transaction type for an extension to the tlm_generic_payload struct

Category
Predefined struct

Description
The tlm_extension struct is used to define TLM 2.0 data transaction fields that are missing from
tlm_generic_payload but that are required to follow a given protocol (or for any other reason).
You can create a different extension to model each separate protocol. Because each extension is built on
the generic payload type, it is easy to switch between protocols.
The tlm_extension base struct does not have any public members.
Notes

You can add an extension to a given tlm_generic_payload type procedurally by using the
set_extension() or via constraints when generating payloads in sequences. For examples, see the
See Also references below.

Specman e Language Reference


1999-2015

506

Product Version 15.1


All Rights Reserved.

Extensions are stored in the generic payload by type, which means that only one instance of any
given extension type can be placed in the list. Any subsequent calls to set_extension() with the same
extension type will result in replacing the existing extension object with the new one.
SystemC also declares a tlm_extension class, but in SystemC it is a template class for technical
reasons. In e, it is a regular struct.

See Also

tlm_generic_payload on page 507

Data Types Definition in the UVM Multi-Language Reference

TLM 2.0 e Interface Example in the UVM Multi-Language Reference, in particular:

Using Types Derived from tlm_generic_payload

Using Arrays in Extensions

6.15.4

tlm_generic_payload

Purpose
Transaction type for memory-mapped bus modeling

Category
Predefined transaction type

Definition
struct tlm_generic_payload like any_sequence_item {
// fields
%m_address: uint(bits:64);
%m_command: tlm_command;
%m_data: list of byte;
%m_length: uint;
%m_response_status: tlm_response_status;
%m_byte_enable: list of byte;
%m_byte_enable_length: uint;
%m_streaming_width: uint;
%m_extensions: list of tlm_extension;

Specman e Language Reference


1999-2015

507
.

Product Version 15.1


All Rights Reserved.

Description
The tlm_generic_payload struct is intended to handle all TLM 2.0 general-purpose data transactions
and, with extensions, all data transaction that must follow a given protocol. Because the same
transaction type is used as the basis for all data transactions in TLM 2.0, you can use it to send data to or
from any TLM 2.0 socket, in any TLM 2.0 model.
Note

tlm_generic_payload is not a UVM object and cannot be used with TLM1.0 ports.

tlm_generic_payload Fields
The following table describes the fields defined for tlm_generic_payload.
Table 6-2

tlm_generic_payload struct fields

Field Name
%m_address: uint(bits:64)

Address for the operation.

%m_command: tlm_command

Operation type. See tlm_command on page 504.

%m_data: list of byte

Data read or to be written.

%m_length: uint

The number of bytes to be copied to or from the m_data array.


This field is initialized to zero, which is an invalid value. Thus,
you must set this field explicitly when you define the
tlm_generic_payload struct.
Note To transfer zero data bytes, set m_command to
TLM_IGNORE_COMMAND. For more information, see the
description of TLM_IGNORE_COMMAND in tlm_command
on page 504.

%m_response_status:
tlm_response_status

Status of the operation. See tlm_response_status on page 512.

%m_dmi: bool

Cadence does not support the direct memory interface (DMI).


Thus, do not change the default value, which is FALSE.

%m_byte_enable: list of byte

Indicates valid m_data array elements. The default value is zero


(null pointer).
For information about how this attribute is used, see the
description of the byte enable pointer attribute in the IEEE
Standard for Standard SystemC Language Reference Manual
(IEEE1666-2011).

Specman e Language Reference


1999-2015

508

Product Version 15.1


All Rights Reserved.

Table 6-2

tlm_generic_payload struct fields

Field Name
%m_byte_enable_length: uint

Indicates the number of elements in the byte enable array. The


default value is zero. Note that this attribute is ignored if the
value of m_byte_enable is zero.
For information about how this attribute is used, see the
description of the byte enable length attribute in the IEEE
Standard for Standard SystemC Language Reference Manual
(IEEE1666-2011).

%m_streaming_width: uint

The number of bytes transferred on each beat. The default value


is zero.
Streaming affects the way a component interprets the data array.
A stream consists of a sequence of data transfers occurring on
successive notional beats, each beat having the same start address
as given by the generic payload address attribute.
For information about how this attribute is used, see the
description of the streaming width attribute in the IEEE Standard
for Standard SystemC Language Reference Manual
(IEEE1666-2011).

%m_extensions: list of
tlm_extension

Note This list is empty by default. To add extensions to this list,


see the descriptions of set_extension() and get_extension() in
Table 6-3 on page 510.

tlm_generic_payload Methods
The following table describes the predefined methods for this struct.

Specman e Language Reference


1999-2015

509
.

Product Version 15.1


All Rights Reserved.

Table 6-3

tlm_generic_payload Predefined Struct Methods

Method Name

Method Description

set_extension(ext: tlm_extension)

Adds the specified extension to the generic payloads


extension list. Returns the previous value of this
extension type, if one existed; otherwise, returns NULL.
The following example illustrates the use of
set_extension():
struct extension1 like tlm_extension {
%m_uint : uint;
%m_int: int;
...
};
struct extension2 like tlm_extension {
%m_struct : a_struct;
...
unit initiator_unit {
i: tlm_initiator_socket is instance;
...
drive()@sys.any is {
var gp : tlm_generic_payload;
gp = new;
var ext1: extension1 = new;
...
gp.set_extension(ext1);
var ext2: extension2 = new;
...
gp.set_extension(ext2);
var status :=
i$.nb_transport_fw(gp,phase,t);
...

get_extension(extension-type-name) :
tlm_extension

Returns the current value of the specified extension type


if such an extension was previously added to the list;
otherwise, returns NULL.

get_extensions() : list of tlm_extension

Returns the list of extensions.

Specman e Language Reference


1999-2015

510

Product Version 15.1


All Rights Reserved.

Example
The following burst in e is defined as a tlm_generic_payload:
data_list: list of byte;
keep data_list.size() < 100;
!burst: tlm_generic_payload;
gen burst keeping {
it.m_command == TLM_WRITE_COMMAND;
it.m_address == 0x1000;
it.m_data == data_list;
it.m_length == data_list.size();
it.m_byte_enable == {};
it.m_byte_enable_length == 0;
it.m_streaming_width == 1;
it.m_response_status == TLM_INCOMPLETE_RESPONSE;
it.m_extensions.size() == 0;
};

See Also

Data Types Definition in the UVM Multi-Language Reference

TLM 2.0 e Interface Example in the UVM Multi-Language Reference

6.15.5

tlm_phase_enum

Purpose
Identifies the current phase of the communication protocol for nb_transport_fw() or
nb_transport_bw().

Category
Enumerated type

Description
Represents the standard sequence of phases for a given transaction through a given socket for the
nonblocking interfacebegin a request, end the request, begin a response, and end the response.

Specman e Language Reference


1999-2015

511
.

Product Version 15.1


All Rights Reserved.

The intent is that the phase argument inform components as to whether and when they are permitted to
read or modify the attributes of a transaction. If the rules of a protocol allow a given component to
modify the value of a transaction attribute during a particular phase, then that component can modify the
value at any time during that phase and any number of times during that phase.
The current phase is included as an argument to by nonblocking nb_transport_fw() and
nb_transport_bw() transport methods. For more information about how the phases work, see Phases
of a Non-Blocking Transfer on page 495.
Possible values for this enumerated type are as follows:
type tlm_phase_enum: [UNINITIALIZED_PHASE=0,
BEGIN_REQ=1,
END_REQ,
BEGIN_RESP,
END_RESP];

These values are described below.

UNINITIALIZED_PHASE No phase has started.

BEGIN_REQThe request has started.

END_REQThe request has completed.

BEGIN_RESPThe response has started.

END_RESPThe response has completed.

See Also

nb_transport_fw() on page 493

nb_transport_bw() on page 497

tlm_sync_enum on page 514

The example in Slave Driver (BFM) Using the Initiator Socket in the UVM Multi-Language Reference.
illustrates checking and setting phases appropriately during a non-blocking transfer.

6.15.6

tlm_response_status

Purpose
Indicates the current status of the operation for a given TLM-2 transaction.

Specman e Language Reference


1999-2015

512

Product Version 15.1


All Rights Reserved.

Category
Enumerated type

Description
The tlm_response_status value is an attribute of the generic payload and indicates the current status of
the transaction operation.
Possible values for this enumerated type are as follows:
type tlm_response_status: [TLM_INCOMPLETE_RESPONSE=0,
TLM_OKAY_RESPONSE=1,
TLM_GENERIC_ERROR_RESPONSE=-1,
TLM_ADDRESS_ERROR_RESPONSE=-2,
TLM_COMMAND_ERROR_RESPONSE=-3,
TLM_BURST_ERROR_RESPONSE=-4,
TLM_BYTE_ENABLE_ERROR_RESPONSE=-5,];

These values are described below.

TLM_INCOMPLETE_RESPONSE The transaction has not yet been delivered to the target or
the transaction operation has not yet been executed by the target.
TLM_OKAY_RESPONSEThe transaction operation completed successfully (both read and
write operations).
TLM_GENERIC_ERROR_RESPONSEThe operation had an error (can be used by the target
to indicate any sort of error).
TLM_ADDRESS_ERROR_RESPONSEThe transaction address is out of range or the operation
failed because of the value of the address given in the transaction.
TLM_BURST_ERROR_RESPONSEAn invalid burst was specified. (the target is unable to
execute the operation with the given data length).
TLM_BYTE_ENABLE_ERROR_RESPONSEEither the target does not support byte enables
or the value of the byte_enable attribute or the byte_enable_length attribute of the generic payload
caused an error.

See Also

tlm_generic_payload on page 507

b_transport() on page 489

nb_transport_fw() on page 493

nb_transport_bw() on page 497

Using e TLM 2.0 Sockets in the Specman Integrators Guide

Specman e Language Reference


1999-2015

513
.

Product Version 15.1


All Rights Reserved.

Multi-Language TLM 2.0 in the UVM Multi-Language Reference Manual

6.15.7

tlm_sync_enum

Purpose
Identifies the synchronization status of the transaction for nb_transport_fw() and nb_transport_bw().

Category
Enumerated type

Description
Each phase (tlm_phase_enum value) of a non-blocking TLM 2.0 transmission is associated with
permission to modify the attributes of the transaction. Both nb_transport_fw() and nb_transport_bw()
return a tlm_sync_enum value, which indicates both the synchronization status of the transaction and
whether the transaction attributes have been modified.
Possible values for tlm_sync_enum are as follows:
type tlm_sync_enum: [TLM_ACCEPTED,
TLM_UPDATED,
TLM_COMPLETED];

These values are described below.

TLM_ACCEPTED The transaction has been accepted. Neither the transaction object, the phase,
nor the delay arguments have been modified.
TLM_UPDATEDThe transaction has been modified. The transaction object, the phase, or the
delay arguments may have been modified.
TLM_COMPLETEDThe transaction execution has completed. The transaction object, the phase,
or the delay arguments may have been modified. There will be no further transport calls associated
with this transaction.

See Also

nb_transport_fw() on page 493

nb_transport_bw() on page 497

tlm_phase_enum on page 511

Using e TLM 2.0 Sockets in the Specman Integrators Guide

Specman e Language Reference


1999-2015

514

Product Version 15.1


All Rights Reserved.

Multi-Language TLM 2.0 in the UVM Multi-Language Reference Manual

6.16 e TLM 2.0 Socket Binding Declaration


6.16.1

connect() for e TLM 2.0 Sockets

Purpose
Connects an e TLM 2.0 initiator socket to a TLM 2.0 target socket.

Category
e TLM 2.0 pseudo-method

Syntax
initiator-socket-exp.connect(target-socket-exp)
initiator-socket-exp.connect(empty | undefined)
initiator-socket-exp.connect(external_uvm_path)

Syntax Examples
i_sckt.connect("top.mem_0.tsocket");
i_sckt.connect(empty);

Parameters
initiator-socket-exp

An e TLM 2.0 initiator socket expression.

target-socket-exp

An e TLM 2.0 initiator socket expression.

empty

Defines a disconnected e TLM 2.0 initiator socket. In this case, invoking


a method on initiator-socket-exp is like calling an empty port.
When initiator-socket-exp is bound to empty, this must be the only
connection it has.

Specman e Language Reference


1999-2015

515
.

Product Version 15.1


All Rights Reserved.

undefined

Defines a disconnected e TLM 2.0 initiator socket. In this case, invoking


a method on initiator-socket-exp causes a run-time error.
When initiator-socket-exp is bound to undefined, this must be the only
connection it has.

external-uvm-path

Path to a specific external TLM 2.0 target socket.

Description
This method creates a connection from initiator-socket-exp. You can bind both e2e and external target
sockets with connect().
Notes

Connection of TLM 2.0 sockets is unidirectional: An initiator socket can connect to its target socket,
but the target socket cannot connect to the initiator socket.
The connect() method can be called only during the connect_ports() or connect_pointers() phase.
Declarative connection using keep bind() and procedural connection using do_bind() are not
supported for sockets.
Procedural binding mechanisms are applied at the end of the synchronized elaboration phase.
When used with TLM 2.0 sockets and interface ports, connect() is supported for e2e and external
ports whereas, when used with method ports, connect() is supported for e2e ports only. connect()
for method ports is described in connect() for e2e Method Ports on page 454.

Example
extend MASTER simple_driver {
. . .
connect_ports() is also {
i_sckt.connect("top.mem_0.tsocket");
};
};

See Also

e TLM 2.0 Socket Declaration and Predefined Methods on page 486

e TLM 2.0 Predefined Structs and Enumerated Data Types on page 504

Using e TLM 2.0 Sockets in the Specman Integrators Guide

Multi-Language TLM 2.0 in the UVM Multi-Language Reference Manual

Specman e Language Reference


1999-2015

516

Product Version 15.1


All Rights Reserved.

Methods

This chapter contains the following sections:

Defining and Extending Methods on page 517

method is on page 518

method @event is on page 521

method [@event] is also | first | only on page 525

method [@event] is undefined | empty on page 532

Invoking Methods on page 535

tcm() on page 535

start tcm() on page 537

method() on page 540

compute method() on page 542

return on page 543

See Also

Chapter 23 Predefined Methods

Working with Regular Methods and TCMs in Creating e Testbenches

7.1

Defining and Extending Methods

method is on page 518

method @event is on page 521

method [@event] is also | first | only on page 525

Specman e Language Reference


1999-2015

517
.

Product Version 15.1


All Rights Reserved.

method [@event] is undefined | empty on page 532

method ... is C routine in the Specman Integrators Guide

See Also

Extending Methods in When Subtypes on page 246

Restrictions on Like Inheritance on page 261

7.1.1

method is

Purpose
Declare a regular method

Category
Struct member

Syntax
[final] method-name ([parameter-list]) [: return-type] is {action;...}
Syntax Example
struct print {
print_length() is { out("The length is: ", length); };
};

Parameters
final

Specifies that the method cannot be extended or redefined in this strut or any of its
subtypes. This modifier is used when the library creator wants to make sure a
method will not change, while still allowing the library user to invoke it.
Standard methods inherited from types such as any_struct or any_sequence_item
cannot be redefined as final.

method-name

A legal e name. See Chapter 1 e Basics for more information on names.

Specman e Language Reference


1999-2015

518

Product Version 15.1


All Rights Reserved.

parameter-list

A list composed of zero or more parameter declarations of the form param-name:


[*]param-type [=default-exp] separated by commas. The parentheses around the
parameter list are required even if the parameter list is empty.
param-name

A legal e name. See Chapter 1 e Basics for more information on


names.

When an asterisk is prefixed to a scalar parameter type, the


location of the parameter, not its value, is passed. When an
asterisk is prefixed to a list or struct type, the method can
completely replace the struct or list. See Parameter Passing in
Methods in Creating e Testbenches for more information.

param-type

Specifies the parameter type.

default-exp

If given, must be a legal constant e expression of the right type


(see Default Parameter Values in Creating e Testbenches).

return-type

For methods that return values, specifies the data type of the return value. See
Chapter 2 Data Types for more information.

action;...

A list of zero or more actions. Actions that consume time are illegal in the action
block of a regular method. For information on actions, see Actions on page 46.

Description
An e method is an operational procedure containing actions that define its behavior. A method can have
parameters, local variables, and a return value. You can define a method only within a struct, and you
must create an instance of the struct before you can execute the method. When a method is executed, it
can manipulate the fields of that struct instance.

Restrictions
The following restrictions apply to all methods:

The maximum number of parameters you can declare for a method is 14.
You can work around this restriction by passing a compound parameter such as a struct or a list.

You cannot define methods with variable argument lists.


You can work around this restriction by passing a list, which can have variable lengths, or a struct,
which can have conditional fields. For example, the following method accepts a list of structs, and
performs appropriate operations on each struct in the list, depending on its type:
m(l: list of any_struct) is {
for each (s) in l do {

Specman e Language Reference


1999-2015

519
.

Product Version 15.1


All Rights Reserved.

if s is a packet (p) then {};


if s is a cell (c) then {};
};
};

This method can then be called as follows:


m({my_cell; my_packet});

Example of a Regular Method


This example shows a method that adds two parameters and returns the result. result is an implicit
variable of the declared return type int.
sum(a: int, b: int): int is {
result = a + b;
};

It is legal to assign to the result variable implicitly by using the following alternate syntax:
sum(a: int, b: int): int is {
return a + b;
};

Examples of final Methods


The following example defines the update_states() method as final, so that it cannot be changed by the
defining struct or any of its subtypes:
final update_states() is {
prev_clk_state = cur_state;
cur_state = new_state;
if pref_clk_state.state == cur_state.state {
new_state = prev_clk_state;
} else {
new_state = prev_state;
prev_state = prev_clk_state;
};
};

The following struct defines a private field, my_id, which is returned by the get_my_id method. Because
it is returned by a final method, the library user can get the value of my_id but cannot change or hook up
to it:
private my_id:uint;
final get_my_id(): uint is {
return my_id;
};
Specman e Language Reference
1999-2015

520

Product Version 15.1


All Rights Reserved.

The following final method ensures that no invalid packets are allowed:
final check_validity(p:packet): bool is {
var signature := compute_signature_C_function(p.body);
result = (signture == p.signature);
...
};

The following example produces a semantic error because it tries to make the init() method final. This
is not allowed because it is a method of any_struct:
final init() is {};

Similarly, the following code produces a semantic error because it tries to make the is_releveant()
method of any_sequence_item a final method:
struct mystruct like any_sequence_item {
final is_relevant(): bool is {
...
};
};

See Also

method @event is on page 521

method [@event] is also | first | only on page 525

method [@event] is undefined | empty on page 532

Rules for Extending Methods in Creating e Testbenches

Invoking Methods on page 535

Parameter Passing in Methods in Creating e Testbenches

Chapter 23 Predefined Methods

Chapter 1 e Basics (in particular, Actions on page 46)

7.1.2

method @event is

Purpose
Declare a time-consuming method

Category
Struct member
Specman e Language Reference
1999-2015

521
.

Product Version 15.1


All Rights Reserved.

Syntax
[final] method-name ([parameter-list]) [: return-type] @event is {action;...}
Syntax Example
struct meth {
main() @pclk is {
wait @ready;
wait [2];
init_dut();
emit init_complete;
};
};

Parameters
final

Specifies that the method cannot be extended or redefined in this strut or any of its
subtypes. This modifier is used when the library creator wants to make sure a
method will not change, while still allowing the library user to invoke it.
Standard methods inherited from types such as any_sequence or
any_sequence_driver cannot be redefined as final.

method-name

A legal e name. See Chapter 1 e Basics for more information on names.

parameter-list

A list composed of zero or more parameter declarations of the form param-name:


[*]param-type [=default-exp] separated by commas. The parentheses around the
parameter list are required even if the parameter list is empty.
param-name A legal e name. See Chapter 1 e Basics for more information on
names.

return-type

When an asterisk is prefixed to a scalar parameter type, the location


of the parameter, not its value, is passed. When an asterisk is prefixed
to a list or struct type, the method can completely replace the struct or
list. See Parameter Passing in Methods in Creating e Testbenches for
more information.

param-type

Specifies the parameter type.

default-exp

If given, must be a legal constant e expression of the right type (see


Default Parameter Values in Creating e Testbenches).

For methods that return values, specifies the data type of the return value. See
Chapter 2 Data Types for more information.

Specman e Language Reference


1999-2015

522

Product Version 15.1


All Rights Reserved.

@event

Specifies a default sampling event that determines the sampling points of the TCM.
This event must be a defined event in e and serves as the default sampling event for
the time consuming method itself as well as for time consuming actions, such as
wait, within the TCM body. Other sampling points can also be added within the
TCM. See Chapter 13 Temporal Expressions for information on defining default
sampling events.

action;...

A list of zero or more actions, either time-consuming actions or regular actions. For
information on actions, see Actions on page 46.

Description
Defines a new time consuming method (TCM). TCMs can execute over multiple cycles and are used to
synchronize processes in an e program with processes or events in the DUT. TCMs can contain actions
that consume time, such as wait, sync, and state machine, and can call other TCMs. Within a single e
program, multiple TCMs can execute either in sequence or in parallel, along separate threads. A TCM
can also have internal branches, which are multiple action blocks executing concurrently.
The main() TCM shown here waits two pclk cycles after the event ready occurs. It calls a method to
initialize the DUT and emits an event when the initialization is complete.
struct meth {
event pclk is rise('top.pclk')@sim;
event ready is rise('top.ready')@sim;
event init_complete;
init_dut() is empty;
main() @pclk is {
wait @ready;
wait [2];
init_dut();
emit init_complete;
};
};

A TCM can specify events other than the default event as sampling points for actions. For example,
adding the @ready sampling event to the wait [2] causes the TCM to wait two ready cycles rather than
two pclk cycles:
main() @pclk is {
wait @ready;
wait [2] @ready;
init_dut();
emit init_complete;
};

Specman e Language Reference


1999-2015

523
.

Product Version 15.1


All Rights Reserved.

For more information on sampling events, see Chapter 12 Events. For more information on temporal
expressions, see Chapter 13 Temporal Expressions.

TCM Restrictions
The following restrictions apply to all TCMs:

The maximum number of parameters you can declare for a TCM is 14.
You can work around this restriction by passing a compound parameter such as a struct or a list.

You cannot define methods with variable argument lists.


You can work around this restriction by passing a list, which can have variable lengths, or a struct,
which can have conditional fields. For example, the following TCM accepts a list of structs, and
performs appropriate operations on each struct in the list, depending on its type:
m(l: list of
for each
if s
if s
};
};

any_struct)@send_data is {
(s) in l do {
is a packet (p) then {};
is a cell (c) then {};

This method can then be called as follows:


start m({my_cell; my_packet});

Example of a TCM
The init_dut TCM shown has two branches running in parallel. The first branch is waiting for a reset
event. The second branch waits for two cycles of cclk and then launches three methods that check the
state of the DUT. If all three checking methods complete before a reset occurs, then the Checking is
complete... message is displayed, and the branch that is waiting for the reset event terminates. If the
reset occurs before the checking methods have completed, they are terminated and the message A reset
has happened... is displayed. The cclk event and the reset event are defined as events in the DUT.
event mready;
event reset is rise('top.reset')@sim;
event cclk is rise('top.cclk')@sim;
init_dut() @cclk is {
first of {
{
wait @reset;
out("A reset has happened...");
};
Specman e Language Reference
1999-2015

524

Product Version 15.1


All Rights Reserved.

{
wait [2];
all of {
{check_bus_controller()};
{check_memory_controller()};
{check_alu()};
};
out("Checking is complete...");
emit mready;
};
};
};

See Also

method is on page 518

method [@event] is also | first | only on page 525

method [@event] is undefined | empty on page 532

Rules for Extending Methods in Creating e Testbenches

Invoking Methods on page 535

Parameter Passing in Methods in Creating e Testbenches

Chapter 13 Temporal Expressions

Chapter 14 Temporal Struct and Unit Members

Chapter 15 Time-Consuming Actions

start tcm() on page 537

Thread Commands in the Specman Command Reference

Semaphore and Locker Methods on page 1276

event on page 662

7.1.3

method [@event] is also | first | only

Purpose
Extend a regular method or a TCM

Category
Struct member

Specman e Language Reference


1999-2015

525
.

Product Version 15.1


All Rights Reserved.

Syntax
method-name ([parameter-list]) [: return-type] [@event-type] is
[also|first|only] {action;...}
Syntax Example
struct meth {
run() is also {
out("Starting main...");
start main();
};
};

Parameters
method-name

A legal e name. See Chapter 1 e Basics for more information on names.

parameter-list

Specifies the same parameter list as defined in the original method, or a


compile-time error is issued. No default values may be specified in the context of a
method extension (see Default Parameter Values in Creating e Testbenches).

return-type

Specifies the same return value as defined in the original method, or a compile-time
error is issued.

@event-type

Specifies the same sampling event as defined in the original method or a


compile-time error is issued.

also

The new action block is appended to the end of the original action block.

first

The new action block is inserted before the original action block.

only

The new action block overrides the original action block.

action;...

A list of zero or more actions. Actions that consume time are illegal in the action
block of a regular method. For information on actions, see Actions on page 46.

Description
The following example extends the structs predefined method run() to start a user-defined TCM. (A
TCM is a time-consuming method that is distinguished from a regular method by the presence of
@event and can use time-consuming actions such as sync and wait.)
run() is also {
out("Starting main...");
start main();
};
Specman e Language Reference
1999-2015

526

Product Version 15.1


All Rights Reserved.

This example extends the init_dut() TCM to start another user-defined TCM, load_mem. This TCM is
called after all the checking methods in the original method have completed successfully.
extend check_all {
load_mem() @cclk is {out("Loading memory...");};
init_dut() @cclk is also {
wait @mready;
start load_mem();
};
};

Notes

Methods that are defined as final cannot be extended or redefined.


Data flows in and out of the previous method definition in the standard way. Changes to the values
of parameter variables in an is first extension are visible in the previous definition, and the value
returned from the previous definition is visible in the result variable of an is also extension. However,
the opposite does not hold. Writing to the result variable in an is first extension has no effect, and
the parameters variable in an is also extension are set to the original valued passed by the caller. This
behavior is true for both compiled code and interpreted code.
After extending a TCM in a like child, that TCM cannot be extended in the parent.
The following rules apply for return actions in extended methods, as illustrated in Figure 7-1 on
page 528, Figure 7-2 on page 529 and Figure 7-3 on page 530:

When an extension issues a return, any actions following that return within the extension itself
are not executed.
When a method is extended with is also, the extension starts executing right after the older
version of the method completes execution.
is also extensions are executed regardless of whether the older version of the method issues a
return or not.
When a method is extended with is first, the older version of the method is never executed if
the extension issues a return.
When a method is extended with is only, the older version of the method is never executed,
whether the extension issues a return or not.

Figure 7-1 on page 528 shows how a method with an is also extension is executed. The older version
executes first and then the is also extension. Notice that the This is also2... statement is not executed
because it follows a return.

Specman e Language Reference


1999-2015

527
.

Product Version 15.1


All Rights Reserved.

Figure 7-1

Execution of is also Method Extension


module methods1.e
<'
struct meth {
m() is {
out("This is");
};
};

older
version of
method

extend sys {
mi:meth;
};

is also

extend meth {
m() is also {
out("This is also");
return;
out("This is also2");
};
};
'>
Result
This is
This is also

Figure 7-2 on page 529 shows the same method extended again, this time with is first. If a return

statement is included in the is first extension, the older version of the method (the original method
definition and the is also extension) do not execute. If the return statement is deleted, the is first
extension executes and then the older version of the method executes.

Specman e Language Reference


1999-2015

528

Product Version 15.1


All Rights Reserved.

Figure 7-2

Execution of is first Method Extension

is first

yes
return?
no
older
version of
method

module methods2.e
<'
import methods1.e;
extend meth {
m() is first {
out("This is first");
return;
};
};
'>
Result with a return in is first
This is first
Result with no return in is first
This is first
This is...
This is also

Figure 7-3 on page 530 shows another extension with is also. Notice that this new extension executes,
regardless of whether there is a return in the older version of the method or not.

Specman e Language Reference


1999-2015

529
.

Product Version 15.1


All Rights Reserved.

Figure 7-3

Execution of is first Method Extension

older
version of
method

is also

module methods3.e
<'
import methods2.e;
extend meth {
m() is also {
out("This is also3");
};
};
'>
Result with a return in is first
This is first
This is also3
Result with no return in is first
This
This
This
This

is first
is
is also
is also3

Example 1
In this example, the show()method is defined originally to identify the kind of packet. The show()
method extension displays a different version of the message when the packet has an error.
type packet_kind: [ETH, ATM] (bits:8);
struct packet {
kind: packet_kind;
has_error: bool;
show() is {
out("Packet kind is...", kind);
};
when has_error {
show() is only {
out("This packet has an error...");
};
};
};

Specman e Language Reference


1999-2015

530

Product Version 15.1


All Rights Reserved.

Example 2
This example extends the execute() method to return immediately if the top.interrupt signal is active,
without executing any of the actions in the original method. Note that the parameter list in the extension
is the same as the parameter list in the original method definition, and the sampling event must also be
repeated for the extension. Similarly, when the original method definition has a return type, it must be
repeated in the method extension.
struct ctrl_stub {
execute(cmd: ctrl_cmd) @cclk is {
outf("Executing a %s (addr %s) control command\n",
cmd.kind, cmd.addr);
case cmd.kind {
RD: {
wait [2];
};
WR: {
wait [2];
};
};
};
};
extend ctrl_stub {
execute(cmd: ctrl_cmd) @cclk is first {
if ('top.interrupt' == 1) then {
return;
};
};
};

See Also

method is on page 518

method @event is on page 521

method [@event] is undefined | empty on page 532

collect in the Specman Command Reference

Rules for Extending Methods in Creating e Testbenches

Extending Methods in When Subtypes on page 246

Specman e Language Reference


1999-2015

531
.

Product Version 15.1


All Rights Reserved.

7.1.4

method [@event] is undefined | empty

Purpose
Declare an abstract method

Category
Struct member

Syntax
method-name ([parameter-list]) [: return-type] [@event-type] is undefined|empty
Syntax Example
struct packet {
show() is undefined;
};

Parameters
method-name

A legal e name. See Chapter 1 e Basics for more information on names.

parameter-list

A list composed of zero or more parameter declarations of the form param-name:


[*]param-type [=default-exp] separated by commas. The parentheses around the
parameter list are required even if the parameter list is empty.

return-type

param-name

A legal e name. See Chapter 1 e Basics for more information


on names.

When an asterisk is prefixed to a scalar parameter type, the


location of the parameter, not its value, is passed. When an
asterisk is prefixed to a list or struct type, the method can
completely replace the struct or list. See Parameter Passing in
Methods in Creating e Testbenches for more information.

param-type

Specifies the parameter type.

default-exp

If given, must be a legal constant e expression of the right type


(see Default Parameter Values in Creating e Testbenches).

For methods that return values, specifies the data type of the return value. See
Chapter 2 Data Types for more information.

Specman e Language Reference


1999-2015

532

Product Version 15.1


All Rights Reserved.

@event-type

Specifies a default sampling event that determines the sampling points of the TCM.
This event must be a defined event in e and serves as the default sampling event for
the TCM itself as well as for time consuming actions, such as wait, within the TCM
body. Other sampling points can also be added within the TCM.

undefined

No action block is defined for the method yet; an action block must be defined in a
subsequent module before this method is called. A runtime error is issued if it is
called before it is defined.

empty

The action block is empty, but no error is issued if it is called. Empty


value-returning methods return the default value for the type.

Description
Declares an abstract regular method or an abstract TCM with no defined functionality. Abstract methods
are place holders that you can extend at a later point. A TCM is a time-consuming method that is
distinguished from a regular method by the presence of @event and can use time-consuming actions
such as sync and wait.

Notes
The following restrictions apply to all abstract methods:

a final method cannot be undefined or empty.

The maximum number of parameters you can declare is 14.


You can work around this restriction by passing a compound parameter such as a struct or a list.

You cannot define methods with variable argument lists.


You can work around this restriction by passing a list, which can have variable lengths, or a struct,
which can have conditional fields.

Example
Undefined or empty methods are often used in base types. This example declares an undefined (abstract)
method show() in the base struct packet and defines the appropriate functionality in the Ethernet packet
and IEEE packet subtypes. The show() method is left undefined for theforeign packet subtype.
type packet_protocol: [Ethernet, IEEE, foreign];
struct packet {
protocol: packet_protocol;
size: int [0..1k];
data[size]: list of byte;
Specman e Language Reference
1999-2015

533
.

Product Version 15.1


All Rights Reserved.

show() is undefined;
};
extend Ethernet packet {
e_field: int;
show() is {out("This is an Ethernet packet")};
};
extend IEEE packet {
i_field: int;
show() is {out("This is an IEEE packet")};
};
extend
a:
b:
c:

sys {
foreign packet;
Ethernet packet;
IEEE packet;

run() is also {
b.show();
c.show();
a.show();
};
};

Result
Notice that trying to invoke the show() method for the foreign packet subtype (the a.show() line)
produces an error message since the show() method is undefined for that subtype.
Specman > test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
This is an Ethernet packet
This is an IEEE packet
*** Error: Calling an undefined method: packet.show()
Specman >

See Also

method is on page 518

Specman e Language Reference


1999-2015

534

Product Version 15.1


All Rights Reserved.

method @event is on page 521

method [@event] is also | first | only on page 525

Rules for Extending Methods in Creating e Testbenches

7.2

Invoking Methods

The following sections describe how you can invoke a TCM:

tcm() on page 535

start tcm() on page 537

The following sections describe how you can call regular methods:

method() on page 540

compute method() on page 542

The last section describes the return action, which causes an immediate return from the current method
to the method that called it. The execution of the calling method then continues:

return on page 543

See Also

Calling e Methods from C in the Specman Integrators Guide

7.2.1

tcm()

Purpose
Call a TCM

Category
Action or expression

Syntax
[[struct-exp].]method-name([parameter-list])
Syntax Example
init_dut();
Specman e Language Reference
1999-2015

535
.

Product Version 15.1


All Rights Reserved.

Parameters
struct-exp

The pathname of the struct that contains the method. If the struct expression is
missing, the implicit variable it is assumed. If both struct expression and the period (.)
are missing, the method name is resolved according to the scoping rules. In other
words,

.init_dut() means it.init_dut()


init_dut() means me.init_dut(), or if that does not exist, global.init_dut()

See Chapter 1 e Basics for more information on naming resolution.


method-name

The method name as specified in the method definition.

parameter-list

A list of zero or more expressions separated by commas, one for each parameter in the
parameter list of the method declaration. Parameters are passed by their relative
position in the list. Parameters at the end of the parameter list may be omitted if the
method declaration specifies defaults for them (seeDefault Parameter Values in
Creating e Testbenches). The parentheses around the parameter list are required even
if the parameter list is empty.

Description
You can call a TCM only from another TCM.
A TCM that does not return a value can be started (see start tcm() on page 537) or called. A call of a
TCM that does not return a value is syntactically an action.
A call of a TCM that does return a value is an expression, and the return type of the TCM must conform
to the type of the variable or field it is assigned to.
A called TCM begins execution either when its sampling event occurs or immediately, if the sampling
event has already occurred for the current Specman tick.
The calling TCM waits until the called TCM returns before continuing execution. For this reason, a
called TCM is considered a subthread of the calling TCM and shares the same thread handle (thread ID)
with the calling TCM. In contrast, a started TCM runs in parallel with the TCM that started it, on a
separate thread.

Restrictions

You cannot call a TCM from a regular method; you must call it from another TCM. To invoke a TCM
from within a regular method, use start.
You cannot call a TCM from within the following scopes:

Any list pseudo method

Specman e Language Reference


1999-2015

536

Product Version 15.1


All Rights Reserved.

A new with body

A dut_error body

Any message

A try block for fixing or bypassing an error

Example
This example shows how to call a TCM from another TCM.
struct meth {
event pclk is rise('top.pclk')@sim;
event ready is rise('top.ready')@sim;
event init_complete;
init_dut() @pclk is empty;
main() @pclk is {
wait @ready;
wait [2];
init_dut();
emit init_complete;
};
};

See Also

start tcm() on page 537

Chapter 15 Time-Consuming Actions

Struct Hierarchy and Name Resolution on page 54

Invoking Methods on page 535

Rules for Extending Methods in Creating e Testbenches

Parameter Passing in Methods in Creating e Testbenches

7.2.2

start tcm()

Purpose
Start a TCM

Category
Action
Specman e Language Reference
1999-2015

537
.

Product Version 15.1


All Rights Reserved.

Syntax
start [[struct-exp].]method-name([parameter-list])
Syntax Example
start main();

Parameters
struct-exp

The pathname of the struct that contains the method. If the struct expression is
missing, the implicit variable it is assumed. If both struct expression and the period (.)
are missing, the method name is resolved according to the scoping rules. See Chapter
1 e Basics for more information on naming resolution.

method-name

The method name as specified in the method definition.

parameter-list

A list of zero or more expressions separated by commas, one for each parameter in the
parameter list of the method declaration. Parameters are passed by their relative
position in the list. Parameters at the end of the parameter list may be omitted if the
method declaration specifies defaults for them (seeDefault Parameter Values in
Creating e Testbenches). The parentheses around the parameter list are required even
if the parameter list is empty.

Description
You can use a start action within another method, either a TCM or a regular method. A started TCM
begins execution either when its sampling event occurs or immediately, if the sampling event has
already occurred for the current Specman tick.
A started TCM runs in parallel with the TCM that started it on a separate thread. A started TCM has a
unique thread handle (thread ID) that is assigned to it automatically by the scheduler. You can retrieve
this handle using one of the predefined methods of the scheduler.
The recommended way to start an initial TCM, which can then invoke other TCMs, is to extend the
related structs predefined run() method.

Notes

You can start a TCM that has a return value with a start action in a context that requires an action,
but its return value is ignored.
By default, you cannot start a TCM that has a return value with a start action in a context that requires
an expression. Specman issues an error in this case. You can change the severity level of this message.
See Example 2 on page 539

Specman e Language Reference


1999-2015

538

Product Version 15.1


All Rights Reserved.

You cannot start a TCM before the run phase begins or after the check phase begins. See Global
Methods on page 1140 for more information on test phases.

Example 1
This example shows how to extend a structs run() method to start a TCM. Note that the start syntax
omits the default sampling event.
struct meth {
event clk is rise('top.clk');
run() is also {
out("Starting main...");
start main();
};
};

Example 2
This example shows that although you can start a TCM that has a return value in a context that requires
an action, you cannot do so in a context that requires an expression.
extend sys {
event clk is rise('top.clk');
my_tcm(): int @clk is {return
run() is also {
--print (start my_tcm());
--var x:= start my_tcm();
start my_tcm(); --This is
};

1};
This is an ERROR
This is an ERROR
0K

};

See Also

Global Method run_test() on page 1145

The run() Method of any_struct or any_unit on page 1192

Chapter 15 Time-Consuming Actions

Struct Hierarchy and Name Resolution on page 54

Invoking Methods on page 535

Rules for Extending Methods in Creating e Testbenches

Parameter Passing in Methods in Creating e Testbenches

Specman e Language Reference


1999-2015

539
.

Product Version 15.1


All Rights Reserved.

7.2.3

method()

Purpose
Call a regular method

Category
Action or expression

Syntax
[[struct-exp].]method-name([parameter-list])
Syntax Example
tmp1 = get_free_area_size(size, taken);

Parameters
struct-exp

The pathname of the struct that contains the method. If the struct expression is
missing, the implicit variable it is assumed. If both struct expression and the period (.)
are missing, the method name is resolved according to the scoping rules. See Chapter
1 e Basics, for more information about naming resolution.

method-name

The method name as specified in the method definition.

parameter-list

A list of zero or more expressions separated by commas, one for each parameter in the
parameter list of the method declaration. Parameters are passed by their relative
position in the list. Parameters at the end of the parameter list may be omitted if the
method declaration specifies defaults for them (seeDefault Parameter Values in
Creating e Testbenches). The parentheses around the parameter list are required even
if the parameter list is empty.

Description
The proper context for calling a regular method depends on whether the method returns a value or not.

If the method returns a value, it is an expression and can be called from any context where an
expression is valid.
If the method does not return a value, it is an action and can be called from any context where an
action is valid.

Specman e Language Reference


1999-2015

540

Product Version 15.1


All Rights Reserved.

Example 1
Two common contexts for calling value-returning methods are shown below.
m() is {
var tmp1: int;
tmp1 = get_free_area_size(size, taken);
print tmp1;
};
keep length <= get_free_area_size(size, taken);

When placed on the right-hand side of an assignment operator, the methods return value type must
conform to the type of the variable or field it is assigned to.

Example 2
In some cases you may want to call a value-returning method without using the value that is returned. To
do this, you can use the compute action. In the example shown below, the m() method increments the
counter variable, but does not use the value returned.
inc_counter() : int is {
counter += 1;
result = counter;
};
m() is {
if 'top.b' > 15 {compute inc_counter();};
};

Example 3
You can call regular methods that do not return values either from other methods, including TCMs, from
the Specman command line or from action blocks associated with other constructs, as shown below.
event alu_watcher is {rise('inst_start') exec {
var i: inst;
i = new;
instructions.add(i);
};
};

See Also

compute method() on page 542

Struct Hierarchy and Name Resolution on page 54

Parameter Passing in Methods in Creating e Testbenches

Specman e Language Reference


1999-2015

541
.

Product Version 15.1


All Rights Reserved.

Rules for Extending Methods in Creating e Testbenches

7.2.4

compute method()

Purpose
Compute a regular method

Category
Action

Syntax
compute [[struct-exp].]method-name([parameter-list])
Syntax Example
if 'top.b' > 15 {compute inc_counter();};

Parameters
struct-exp

The pathname of the struct that contains the method. If the struct expression is
missing, the implicit variable it is assumed. If both struct expression and the period (.)
are missing, the method name is resolved according to the scoping rules. See Chapter
1 e Basics, for more information about naming resolution.

method-name

The method name as specified in the method definition.

parameter-list

A list of zero or more expressions separated by commas, one for each parameter in the
parameter list of the method declaration. Parameters are passed by their relative
position in the list. Parameters at the end of the parameter list may be omitted if the
method declaration specifies defaults for them (seeDefault Parameter Values in
Creating e Testbenches). The parentheses around the parameter list are required even
if the parameter list is empty.

Description
In some cases you may want to call a value-returning method without using the value that is returned. To
do this, you can use the compute action.

Specman e Language Reference


1999-2015

542

Product Version 15.1


All Rights Reserved.

Example
In the example shown below, the m() method increments the counter variable, but does not use the value
returned.
inc_counter() : int is {
counter += 1;
result = counter;
};
m() is {
if 'top.b' > 15 {compute inc_counter();};
};

See Also

method() on page 540

Struct Hierarchy and Name Resolution on page 54

Parameter Passing in Methods in Creating e Testbenches

Rules for Extending Methods in Creating e Testbenches

7.2.5

return

Purpose
Return from regular method or a TCM

Category
Action

Syntax
return [exp]
Syntax Example
return i*i;

Parameters
exp

In value-returning methods, an expression specifying the return value is required in each


return action. In non-value-returning methods, expressions are not allowed in return actions.

Specman e Language Reference


1999-2015

543
.

Product Version 15.1


All Rights Reserved.

Description
Returns immediately from the current method to the method that called it. The execution of the calling
method then continues.
It is not always necessary to provide a return action. When a value returning method ends without a
return action, the value of result is returned.

Notes

The return action must be used carefully in method extensions. See method [@event] is also | first
| only on page 525 for more information.

Any actions that follow a return action in the method definition are ignored.

Actions placed in a method extension are performed before the return is executed.

Example 1
This example shows return in a value-returning expression.
<'
extend sys {
sqr(i: uint): uint is {
return i*i;
};
};
'>

Example 2
This example shows return in a non-value-returning method named start_eng().
<'
struct eng_str {
on: bool;
};
struct st_eng {
engine: eng_str;
start_eng(e: eng_str) is {
if e.on then {
out("engine is already on");
return;
};
e.on = TRUE;
out("engine has been turned on");
};
Specman e Language Reference
1999-2015

544

Product Version 15.1


All Rights Reserved.

};
'>

Example 3
For value-returning methods, instead of a return, the special variable result can be assigned and its
value is returned. In the example below, if t is less than 100, the sqr_1() method exits, returning t.
Otherwise, it returns 101.
<'
extend sys {
sqr_1(i: uint): uint is {
var t := i*i;
if t < 100 then {
return t;
};
result = 101;
};
};
'>

Example 4
This example illustrates that any actions following a return action in a method definition or in a method
extension are ignored:
<'
extend sys {
m1(): int is {
return 5;
result = 0;
out ("FAIL");
};
m1():int is also {
return result + 7;
out ("FAIL");
};
};
'>

Result
cmd-prompt> print sys.m1() using dec
sys.m1() = 12

Specman e Language Reference


1999-2015

545
.

Product Version 15.1


All Rights Reserved.

Example 5
The following example shows a method that has a compound type as a return value. In the
get_alpha_num() method, the return action calls another method, select_list(), which has an index, slctr,
which can have a value from 0 to 3.
The select_list() method returns a list of strings (a0, a1, a2, a3, for example), which is determined by the
value (A, B, C, or D) of the ALPHA field.
In the call to select_list(), the slctr value is used as an index into the list of strings returned from the case
action by select_list(). Thus, the get_alpha_num() method, called in run() in sys, returns the string with
index = slctr from the list for case = ALPHA.
<'
type a_type: [A, B, C, D, E];
struct top {
ALPHA: a_type;
slctr: uint (bits: 2);
select_list() :list of string is {
case ALPHA {
A : { return {"a0"; "a1"; "a2";
B : { return {"b0"; "b1"; "b2";
C : { return {"c0"; "c1"; "c2";
D : { return {"d0"; "d1"; "d2";
E : { return {"e0"; "e1"; "e2";
};
};

"a3"};
"b3"};
"c3"};
"d3"};
"e3"};

};
};
};
};
};

get_alpha_num(slctr: uint): string is {


return select_list()[slctr];
};
};
extend sys {
top;
run() is also {
print top.ALPHA;
print top.slctr;
var an_strng: string;
an_strng = top.get_alpha_num(top.slctr);
print an_strng;
};
};
'>

Specman e Language Reference


1999-2015

546

Product Version 15.1


All Rights Reserved.

Result
Running the test ...
top.ALPHA = A
top.slctr = 2
an_strng = "a2" // "a2" is the string with index 2 in list A

See Also

method [@event] is also | first | only on page 525

Specman e Language Reference


1999-2015

547
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

548

Product Version 15.1


All Rights Reserved.

Creating and Modifying e


Variables

The following sections describe how to create and assign values to e variables:

About e Variables on page 549

var on page 550

= on page 552

op= on page 554

<= on page 557

8.1

About e Variables

An e variable is a named data object of a declared type. e variables are declared and manipulated in
methods. They are dynamic; they do not retain their values across subsequent calls to the same method.
The scope of an e variable is the action block that encloses it. If a method contains nested action blocks,
variables in the inner scopes hide the variables in the outer scopes. Variable scoping is described in more
detail in Struct Hierarchy and Name Resolution on page 54.
Some e actions create implicit variables. They are described in more detail in Implicit Variables on page
62.
The following sections describe the actions that create and modify e variables explicitly

var on page 550

= on page 552

op= on page 554

Specman e Language Reference


1999-2015

549
.

Product Version 15.1


All Rights Reserved.

8.2

var

Title
Variable declaration

Category
Action

Syntax
var name [: [type] [= exp]]
Syntax Example
var a: int;

Parameters
name

A legal e name.

type

A declared e type. The type can be omitted if the variable name is the same as the name of
a struct type or if the variable is assigned a typed expression.

exp

The initial value of the variable. If no initial value is specified, the variables are initialized
to 0 for integer types, NULL for structs, FALSE for Boolean types, and lists as empty.

Description
Declares a new variable with the specified name as an element or list of elements of the specified type,
and having an optional initial value.
The var action is legal in any place that an action is legal, and the variable is recognized from that point
on. e variables are dynamic; they do not retain their values across subsequent calls to the same method.
The scope of an e variable is the action block that encloses it. If a method contains nested action blocks,
variables in the inner scopes hide the variables in the outer scopes. Variable scoping is described in more
detail in Struct Hierarchy and Name Resolution on page 54.

Example 1
This example shows the declaration of two variables, one with an assigned initial value:
Specman e Language Reference
1999-2015

550

Product Version 15.1


All Rights Reserved.

<'
extend sys {
m() is {
var a: int;
var m: int = 2 + a;
};
};
'>

Example 2
This example shows the keywords list of used to create a list.
<'
struct packet {
protocol: [atm, eth, other];
len: uint [0..10];
data[len]: list of byte;
};
extend sys {
m() is {
var packets: list of packet;
};
};
'>

Example 3
This example shows a variable declarations with the type omitted. The variable packet is assumed to
be of type packet.
<'
struct packet {
protocol: [atm, eth, other];
len: uint [0..10];
data[len]: list of byte;
};
extend sys {
m() is {
var packet;
};
};
'>

Specman e Language Reference


1999-2015

551
.

Product Version 15.1


All Rights Reserved.

Example 4
In this example, p gets type packet, because that is the type of my_packets[3], and z gets type int,
because 5 has type int.
<'
extend sys {
my_packets: list of packet;
m() is {
var p := my_packets[3];
var z := 5;
};
};
'>

8.3

Purpose
Simple assignment

Category
Action

Syntax
lhs-exp=exp
Syntax Example
sys.u = 0x2345;

Parameters
lhs-exp

A legal e expression that evaluates to a variable of a method, a global variable, a field of


a struct, or an HDL object. The expression can contain the list index operator [n], the bit
access operator [i:j], or the bit concatenation operator %{}.

exp

A legal e expression, either an untyped expression (such as an HDL object) or an


expression of the same type as the left-hand-side expression.

Specman e Language Reference


1999-2015

552

Product Version 15.1


All Rights Reserved.

Description
Assigns the value of the right-hand-side expression to the left-hand-side expression.

Note
There are two other places within the e language which make use of the equal sign. These are a double
equal sign (==) for specifying equality in Boolean expression, and a triple equal sign (===) for the
Verilog-like identity operator. These two operators should not be confused with the single equal sign (=)
assignment operator.

Example 1
This example shows the operators that are allowed in the left-hand-side expression.
<'
struct n {
m() is {
var i: int (bits:16);
var j: int (bits:16);
var lint: list of int = {15;31;63;127};
sys.u = 0x2345;
print sys.u;
lint[0] = 0x98765432;
print lint[0];
i[1:0] = 3;
print i;
%{i,j} = lint[0];
print i, j;
};
};
extend sys {
u:uint;
ni:n;
};
'>

Result
cmd-prompt> sys.ni.m()
sys.u = 0x2345
lint[0] = 0x98765432
i = 0x0003
i = 0x9876
Specman e Language Reference
1999-2015

553
.

Product Version 15.1


All Rights Reserved.

j = 0x5432

Example 2
This example shows the assignment operator used in initialization.
<'
struct packet {
good : bool;
size : [small, medium, large];
length : int;
};
extend sys {
post_generate() is also {
var p : packet = new;
print p;
var q : packet = new good large packet;
print q;
var x := new packet (p) with {
p.length = 5;
print p;
};
};
};
'>

See Also

Reading and Writing HDL Objects in the Specman Integrators Guide

Untyped Expressions on page 166

Assignment Rules on page 169

Precision Rules for Numeric Operations on page 176

Automatic Type Casting on page 180

8.4

op=

Purpose
Compound assignment

Specman e Language Reference


1999-2015

554

Product Version 15.1


All Rights Reserved.

Category
Action

Syntax
lhs-exp op=exp
Syntax Example
sys.c.count1 += 5;

Parameters
lhs-exp

A legal e expression that evaluates to a variable of a method, a global variable, a field of


a struct, or an HDL object.

exp

A legal e expression of the same type as the left-hand-side expression.

op

A binary operator, including binary bitwise operators (except ~), the Boolean operators
and and or, and the binary arithmetic operators.

Description
Performs the specified operation on the two expressions and assigns the result to the left-hand-side
expression.

Example 1
This example shows the compound assignment operator used with arithmetic operators.
<'
struct counter {
count1: uint;
mult: uint;
keep count1 == 0;
keep mult == 2;
};
extend sys {
c: counter;
m() is {
var i: int = 2;
sys.c.count1 += 5;
sys.c.mult *= i;
Specman e Language Reference
1999-2015

555
.

Product Version 15.1


All Rights Reserved.

print sys.c.count1, sys.c.mult;


};
};
'>

Result
cmd-prompt> sys.m()
sys.c.count1 = 0x5
sys.c.mult = 0x4

Example 2
This example shows the compound assignment operator used with the shift operator.
<'
extend sys {
m() is {
var i:int(bits:8) = -1;
print i;
i <<= 4;
print i;
};
};
'>

Result
cmd-prompt> sys.m()
i = 0xff
i = 0xff0

Example 3
This example shows the compound assignment operator used with a Boolean operator.
<'
extend sys {
m() is {
var is_ok: bool = TRUE;
var is_legal: bool;
is_ok or= is_legal;
print is_ok;
};
};
'>

Specman e Language Reference


1999-2015

556

Product Version 15.1


All Rights Reserved.

Result
cmd-prompt> sys.m()
is_ok = TRUE

8.5

<=

Purpose
Delayed assignment

Category
Action

Syntax
[struct-exp.]field-name <= exp
Syntax examples:
da <= da+1;

Parameters
struct-exp

A legal e expression that evaluates to a struct. The default is me.

field-name

A field of the struct referenced by struct-exp.

exp

A legal e expression, either an untyped expression (such as an HDL object) or an


expression of the same type as the left-hand-side expression.

Description
The delayed assignment action assigns a struct field just before the next @sys.new_time after the
action. The purpose is to support raceless coding in e by providing the same results regardless of the
evaluation order of TCMs and temporal expressions. (See Simulation Time and Specman Ticks in
Creating e Testbenches for a description of @sys.new_time.)
Both expressions are evaluated immediately (not delayed) in the current context. The assignment is not
considered a time-consuming action, so you can use it in both TCMs and in regular methods, in on
action blocks and in exec action blocks.
Specman e Language Reference
1999-2015

557
.

Product Version 15.1


All Rights Reserved.

If a field has multiple delayed assignments in the same cycle, they are performed in the specified order.
The final result is taken from the last delayed assignment action.
Unlike in HDL languages, the delayed assignment in Specman does not emit any events; thus, zero
delay iterations are not supported.

Note
The left-hand-side expression in the delayed assignment action can only be a field. Unlike the
assignment action, the delayed assignment action does not accept assignment to any of the following:

A variable of a method

A list item

A bit

A bit slice

A bit concatenation expression

Example
The following example shows how delayed assignment provides raceless coding. In this example there
is one incrementing() TCM, which repeatedly increments the sys.a and sys.da fields, and one
observer() TCM, which observes their value.
<'
extend sys {
!a
: int;
!da : int;
incrementing()@any is {
for i from 1 to 5 {
a = a+1;
da <= da+1;
wait cycle;
};
stop_run();
};
observer()@any is {
while (TRUE) {
out( "observing 'a' as ", a, " observing 'da' as ", da );
wait cycle;
};
};

Specman e Language Reference


1999-2015

558

Product Version 15.1


All Rights Reserved.

run() is also {
start observer();
start incrementing();
};
};
'>

Result
From the results you can see that the value of sys.a observed by the observer() TCM is order-dependent,
depending whether observer() is executed before or after incrementing(). The observed value of
sys.da, however, is independent of the execution order. Even if incrementing() runs first, sys.da gets its
incremented value just before the next new_time event and thus is not be seen by observer().
If observer() runs before incrementing():
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
observing 'a' as 0 observing 'da' as 0
----------------------------observing 'a' as 1 observing 'da' as 1
----------------------------observing 'a' as 2 observing 'da' as 2
----------------------------observing 'a' as 3 observing 'da' as 3
----------------------------observing 'a' as 4 observing 'da' as 4
----------------------------observing 'a' as 5 observing 'da' as 5
----------------------------Last specman tick - stop_run() was called
Normal stop - stop_run() is completed
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

If incrementing() runs before observer():


Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
observing 'a' as 1 observing 'da' as 0
----------------------------observing 'a' as 2 observing 'da' as 1
-----------------------------

Specman e Language Reference


1999-2015

559
.

Product Version 15.1


All Rights Reserved.

observing 'a' as 3 observing 'da' as 2


----------------------------observing 'a' as 4 observing 'da' as 3
----------------------------observing 'a' as 5 observing 'da' as 4
----------------------------Last specman tick - stop_run() was called
Normal stop - stop_run() is completed
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

show delayed in the Specman Command Reference

break on contention in the Specman Command Reference

trace on contention in the Specman Command Reference

Simulation Time and Specman Ticks in Creating e Testbenches

Specman e Language Reference


1999-2015

560

Product Version 15.1


All Rights Reserved.

Control Flow Actions

The following sections describe the control flow actions:

Conditional Actions on page 561

Iterative Actions on page 568

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.1

Conditional Actions

The following conditional actions are used to specify code segments that will be executed only if a
certain condition is met:

if then else on page 561

case labeled-case-item on page 563

case bool-case-item on page 566

9.1.1

if then else

Purpose
Perform an action block based on whether a given Boolean expression is TRUE

Category
Action

Specman e Language Reference


1999-2015

561
.

Product Version 15.1


All Rights Reserved.

Syntax
if bool-exp [then] {action; ...} [else if bool-exp [then] {action; ...}] [else {action; ...}]
Syntax Example
if a > b {print a, b;} else {print b, a};

Notes

Because the if then else clause comprises one action, the semicolon comes at the end of the clause
and not after each action block within the clause. (Do not put a semicolon between the closing curly
bracket for the action block and the else keyword.)
You can repeat the else if clause multiple times.

Parameters
bool-exp

A Boolean expression.

action; ...

A series of zero or more actions separated by semicolons and enclosed in curly


braces.

Description
If the first bool-exp is TRUE, the then action block is executed. If the first bool-exp is FALSE, the else
if clauses are executed sequentially: if an else if bool-exp is found that is TRUE, its then action block is
executed; otherwise the final else action block is executed.
The else if then clauses are used for multiple Boolean checks (comparisons). If you require many else if
then clauses, you might prefer to use a case bool-case-item action.

Example 1
Following is the syntax example expressed as a multi-line example rather than a single-line example.
if a > b then {
print a, b;
}
else {
print b, a;
};

Example 2
The following example includes an else if clause:
Specman e Language Reference
1999-2015

562

Product Version 15.1


All Rights Reserved.

if a_ok {
print x;
}
else if b_ok {
print y;
}
else {
print z;
};

See Also

case labeled-case-item on page 563

case bool-case-item on page 566

Iterative Actions on page 568

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.1.2

case labeled-case-item

Purpose
Execute an action block based on whether a given condition is true

Category
Action

Syntax
case case-exp {labeled-case-item; ... [default[:] {default-action; ...}]}
Syntax Example
case packet.length {
64:
{out("minimal packet")};
[65..256]:
{out("short packet")};
[257..512]: {out("long packet")};
default:
{out("illegal packet length")};
};

Specman e Language Reference


1999-2015

563
.

Product Version 15.1


All Rights Reserved.

Parameters
case-exp

A legal e expression.

labeled-case-item

label-exp[:] action-block
Where

label-exp is an expression that can produce either of the following:

legal equality expression with case-exp


case-exp == label-exp

legal in expression with case-exp


case-exp in label-exp
Note For cases when both are possible (set == set vs. set in set, list == list
vs. list in list), the == expression is always preferred.

action-block is a list of zero or more actions separated by semicolons and


enclosed in curly braces. Syntax: {action;...}

Note For each label-exp, there must be at least one action-block. In other
words, the entire labeled-case-item is repeatable, not just the action-block related
to the label-exp.
default-action; ...

A sequence of zero or more default actions separated by semicolons and enclosed


in curly braces.

Description
Evaluates the case-exp and executes the first action-block for which label-case-item matches the
case-exp. If no label-exp evaluates to TRUE with the case-exp, it executes the default-action block, if
specified.
Note case-exp is evaluated only once. If it has side effects, they occur only once before evaluation
of any label-exp or action block. Thus, even if side effects of label-exp would have caused a different
value in case-exp, the comparison is nevertheless performed against initial case-exp value.
After an action-block is executed, Specman proceeds to the line that immediately follows the entire case
statement.
Table 9-1 indicates the types of expressions that can be produced for label-exp, depending on whether

label-exp follows and equality operator or an in keyword.

Specman e Language Reference


1999-2015

564

Product Version 15.1


All Rights Reserved.

Table 9-1

Expression Types That Can Be Produced for label-exp

Type of case-exp

Type of label-exp for equality

Type of label-exp for in

Any numeric type

Numeric constant
Numeric expression

Numeric list constant


Numeric list expression
Set constant
Set expression

Enum type

Enum item constant of the enum type


Enum expression of the enum type

List of the enum constant


List of the enum expression
Enum constant set

Set

Set

List of set

String

String constant
String expression

List of string constant


List of string expression

Struct type

Struct expression of comparable type

List or struct expression of


comparable type

List of type

List of the type expression

List of list of the type expression

External pointer

External pointer expression

List of external pointer expression

Note If case-exp is untyped (see Untyped Expressions on page 166), the first label-exp defines its
type as regards equality, and subsequent label-exps should conform this type.

Example
case curr_address() {
0: {
// int == int
zero();
};
get_special_list(): {
// int in list of int
special();
};
set_of_values(address_t): { // int in set
legal();
};
default: {
illegal();
};
};

Specman e Language Reference


1999-2015

565
.

Product Version 15.1


All Rights Reserved.

See Also

if then else on page 561

case bool-case-item on page 566

Iterative Actions on page 568

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.1.3

case bool-case-item

Purpose
Execute an action block based on whether a given Boolean comparison is true

Category
Action

Syntax
case {bool-case-item; ... [default[:] {default-action; ...}]}
Syntax Example
case {
packet.length == 64
packet.length in [65..255]
default
};

Specman e Language Reference


1999-2015

{out("minimal packet"); };
{out("short packet"); };
{out("illegal packet"); };

566

Product Version 15.1


All Rights Reserved.

Parameters
bool-case-item

bool-exp[:] action-block
Where
bool-exp is a Boolean expression.
action-block is a list of zero or more actions separated by semicolons and
enclosed in curly braces. Syntax: {action;...}
Note that the entire bool-case-item is repeatable, not just the action-block related
to the bool-exp.

Note For each action-block, there must be at least one bool-exp. In other
words, the entire bool-case-item is repeatable, not just the action-block related to
a given bool-exp.
default-action; ...

A sequence of zero or more actions separated by semicolons and enclosed in curly


braces.

Description
Evaluates the bool-exp conditions one after the other; executes the action-block associated with the first
TRUE bool-exp. If no bool-exp is TRUE, executes the default-action-block, if specified.
After an action-block is executed, Specman proceeds to the line that immediately follows the entire case
statement.
Each of the bool-exp conditions is independent of the other bool-exp conditions, and there is no main
case-exp to which all cases refer (unlike the case labeled-case-item on page 563).
This case action has the same functionality as a single if then else action in which you enter each
bool-case-item as a separate else if then clause.

Example
The bool-exp conditions are totally independent, and can refer to many arbitrary fields and attributes
(not only to a single field as in the example above). For example, here is a set of independent Boolean
conditions:
case {
kind == small {
// condition 1: relates to kind
print "SMALL";
};
a > b {
// condition 2: relates to a and b
print "a > b";
var temp := a;
Specman e Language Reference
1999-2015

567
.

Product Version 15.1


All Rights Reserved.

a = b;
b = temp;
};
a < b && kind == large {
// condition 3: relates to a,b,kind
print "a < b && kind == large";
};
default {print "OTHER"};
// condition 4: default
};

See Also

if then else on page 561

case labeled-case-item on page 563

Iterative Actions on page 568

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.2

Iterative Actions

This section describes the following iterative actions, which are used to specify code segments that will
be executed in a loop, multiple times, in a sequential order:

while on page 568

repeat until on page 570

for each in on page 572

for each in set on page 575

for from to on page 577

for on page 579

9.2.1

while

Purpose
Execute a while loop

Specman e Language Reference


1999-2015

568

Product Version 15.1


All Rights Reserved.

Category
Action

Syntax
while bool-exp [do] {action; ...}
Syntax Example
while a < b {a += 1;};

Parameters
bool-exp

A Boolean expression.

action; ...

A sequence of zero or more actions separated by semicolons and enclosed in curly braces.

Example 1
The while loop in the following example adds 10 to ctr as many times as it takes it to get from 100 to
the value of SMAX in steps of 1.
ctr_assn() is {
var i: uint;
i = 100;
while (i <= SMAX) {
ctr = ctr + 10;
i+=1;
};
};

Example 2
The while loop in the following example assigns top.inc to ctr every two cycles, as long as done
remains FALSE.
lp_read()@clk is {
while (!done) {
wait [2]*cycle;
ctr = top.inc;
};
};

Specman e Language Reference


1999-2015

569
.

Product Version 15.1


All Rights Reserved.

Example 3
The while loop in the following example assigns top.inc to ctr every two cycles, in an endless loop.
It loops until the test run is stopped.
lp_read()@clk is {
while TRUE {
wait [2]*cycle;
ctr = top.inc;
};
};

Description
Executes the action block repeatedly in a loop while bool-exp is TRUE. You can use this construct to set
up a perpetual loop as while TRUE {}.

See Also

repeat until on page 570

for each in on page 572

for each in set on page 575

for from to on page 577

for on page 579

Conditional Actions on page 561

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.2.2

repeat until

Purpose
Execute a repeat until loop

Category
Action

Specman e Language Reference


1999-2015

570

Product Version 15.1


All Rights Reserved.

Syntax
repeat {action; ...} until bool-exp
Syntax Example
repeat {i+=1;} until i==3;

Parameters
action; ...

A sequence of zero or more actions separated by semicolons and enclosed in curly braces.

bool-exp

A Boolean expression.

Description
Execute the action block repeatedly in a loop until bool-exp is TRUE.

Note
A repeat until action performs the action block at least once. A while action might not perform the
action block at all.

Example
repeat {
i+=1;
print i;
} until i==3;

See Also

while on page 568

for each in on page 572

for from to on page 577

for on page 579

Conditional Actions on page 561

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

Specman e Language Reference


1999-2015

571
.

Product Version 15.1


All Rights Reserved.

9.2.3

for each in

Purpose
Execute a for each loop

Category
Action

Syntax
for each [type] [(item-name)] [using index (index-name)]
in [reverse] list-exp [do] {action; ...}
Syntax Example
for each transmit packet (tp) in sys.pkts do {print tp};
// "transmit packet" is a type

Parameters
type

A type of the struct comprising the list specified by list-exp. Elements in the list must
match this type to be acted upon.

item-name

A name you give to specify the current item in list-exp.


If you do not include this parameter, the item is referred to with the implicit variable it.
Cadence recommends that you explicitly name the item to avoid confusion about the
contents of it.

index-name

A name you give to specify the index of the current list item.
If you do not include this parameter, the item is referred to with the implicit variable
index. Cadence recommends that you explicitly name the item to avoid confusion about
the contents of index.

list-exp

An expression that results in a list.

action; ...

A sequence of zero or more actions separated by semicolons and enclosed in curly braces.

Specman e Language Reference


1999-2015

572

Product Version 15.1


All Rights Reserved.

Description
For each item in list-exp, if its type matches type, execute the action block. Inside the action block, the
implicit variable it (or the optional item-name) refers to the matched item, and the implicit variable
index (or the optional index-name) reflects the index of the current item. If reverse is specified, list-exp
is traversed in reverse order, from last to first. The implicit variable index (or the optional index-name)
starts at zero for regular loops, and is calculated to start at (list.size() - 1) for reverse loops.

The it and index Implicit Variables


Each for each in action defines two new local variables for the loop, named by default it and index.
Keep the following in mind:

If loops are nested one inside the other, the local variables of the internal loop hide those of the
external loop. To overcome this hiding, specify the item-name and index-name with unique names.
Within the action block, you cannot assign a value to it or indexor to item-name or index-name.

Example 1
<'
extend sys {
do_it() is {
var numbers := {1; 2; 3};
for each in numbers {
print it;
};
var sum: int;
for each (n) in numbers {
sum += n;
print sum;
};
};
run() is also {
do_it();
};
};
'>

Example 2
for each in reverse pktList do {
// Traverse in reverse order
print it;
// "it" can refer to the various subtypes
};

Specman e Language Reference


1999-2015

573
.

Product Version 15.1


All Rights Reserved.

Example 3
This example shows the use of a multi-dimensional list:
<'
extend sys {
run() is also {
var l: list of list of int = {{1;2;3};{4;5;6};{7;8;9}};
for each in l do {
it.delete(1);
};
for each in l do {
assert it.size() == 2;
};
};
};
'>

Example 4
This example has two for each loops, each of which invokes a method and an out() routine for the
particular subtype (ATM cell or IP cell).
<'
type cell_t: [ATM,IP];
struct cell{
kind: cell_t;
when ATM cell {
meth() is {
outf("ATM cell: ");
};
};
when IP cell {
meth() is {
outf("IP cell: ");
};
};
};
extend sys {
cell_l[20] : list of cell;
run () is also {
for each ATM cell (a) in cell_l {
a.meth();
out(index);
Specman e Language Reference
1999-2015

574

Product Version 15.1


All Rights Reserved.

};
for each IP cell (a) in cell_l {
a.meth();
out(index);
};
}
};
'>

See Also

while on page 568

repeat until on page 570

for each in set on page 575

for from to on page 577

for on page 579

Implicit Variables on page 62

Conditional Actions on page 561

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.2.4

for each in set

Purpose
Iterate a for loop over all items of a set.

Category
Action

Syntax
for each [type] [(item-name)] in [reverse] set set-exp [do] {action; ...}
Syntax Example
for each address_t in set addresses {
process_addr(it);
};

Specman e Language Reference


1999-2015

575
.

Product Version 15.1


All Rights Reserved.

Parameters
type

Type of the variable referring to the current item of the set. Default type is int(bits:*).
Cadence recommends that you explicitly specify the type when possible.

item-name

Name you give to specify the current item in set-exp.


If you do not include this parameter, the item is referred to with the implicit variable it.
Cadence recommends that you explicitly name the item to avoid confusion about the
contents of it.

set-exp

Expression that results in a set.

action; ...

Sequence of zero or more actions separated by semicolons and enclosed in curly braces.

Description
For each item in set-exp, this executes the action block. Inside the action block, the implicit variable it
(or the optional item-name) refers to the current set item. If reverse is specified, set-exp is traversed in
reverse order, from last to first.
Notes

If the set contains numbers out of specified types range, the value is numerically casted, but there
is no check whether or not the value is legal. Therefore, if it cannot be assumed that all items of the
set have proper values for the type, a possible solution is to check the set against set of values of the
type before the loop (see Example 1 on page 576).
If the number of items in a set is very large, it can be impractical to iterate over them all. (For example,
there are 0x100000000 items in set of values of 'int' type, and 0x10000000000000000 items in set
of type of 'time' type.) Therefore, if it cannot be assumed that the set has reasonable number of items,
its size should be checked (for example, by using size()/uint_size() pseudo-methods (see Set Size
Pseudo-Methods on page 1434).

Example 1
var s: set = get_set();
if s.size() > 0 {
if not (s in set_of_values(address_t)) {
dut_error("Set contains out of range values");
}
else {
for each address_t (adr) in set s {
process_address(adr);
};
};
};
Specman e Language Reference
1999-2015

576

Product Version 15.1


All Rights Reserved.

See Also

while on page 568

repeat until on page 570

for each in on page 572

for from to on page 577

for on page 579

Implicit Variables on page 62

Conditional Actions on page 561

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.2.5

for from to

Purpose
Execute a for loop for the number of times specified by from to

Category
Action

Syntax
for var-name from from-exp [down] to to-exp [step step-exp] [do] {action; ...}
Syntax Example
for i from 5 down to 1 do {out(i);};

// Outputs 5,4,3,2,1

Parameters
var-name

A temporary variable of type int.

Specman e Language Reference


1999-2015

577
.

Product Version 15.1


All Rights Reserved.

from-exp, to-exp,
step-exp

Valid e expressions that resolve to type int, uint, or long (unbounded):

If all three variables are of type int, then all three are interpreted as int.
If one or more of the variables is of type uint, then all three are interpreted
as uint.
If one or more of the variables is of type long (unbounded), then all three
are interpreted as long.

For example, in the following code:


for i from 0x1 to -1

The from-exp (0x1) is of type uint and thus the to-exp (-1) is also treated as
a uint. In other words, the -1 is interpreted to be a large positive number
(0xFFFF...), rather than a negative number.
The default value for step-exp is one.
action; ...

A sequence of zero or more actions separated by semicolons and enclosed in


curly braces.

Description
Creates a temporary variable var-name of type int, and repeatedly executes the action block while
incrementing (or decrementing if down is specified) its value from from-exp to to-exp in interval values
specified by step-exp (defaults to 1).
In other words, the loop is executed until the value of var-name is greater than the value of to-exp (if
down is not specified) or until the value of var-name is less than the value of to-exp (if down is
specified). For example, the following line of code prints in one time:
for j from 1 to 1 {out("in");};

Notes

The temporary variable var-name is visible only within the for from to loop in which it is created.
The from-exp is evaluated only once. The to-exp and step-exp are evaluated on each iteration of the
loop.

Example
for i from 2 to 2 * a do {
out(i);
};
for i from 1 to 4 step 2 do {
Specman e Language Reference
1999-2015

578

Product Version 15.1


All Rights Reserved.

out(i);
};
// Outputs 1,3
for i from 4 down to 2 step 2 do {
out(i);
};
// Outputs 4,2

See Also

while on page 568

repeat until on page 570

for each in on page 572

for each in set on page 575

for on page 579

Conditional Actions on page 561

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.2.6

for

Purpose
Execute a C-style for loop

Category
Action

Syntax
for {initial-action; bool-exp; step-action} [do] {action; ...}
Syntax Example
for {i=0; i<=10; i+=1} do {out(i);};

Parameters
initial-action

An action.

bool-exp

A Boolean expression

Specman e Language Reference


1999-2015

579
.

Product Version 15.1


All Rights Reserved.

step-action

An action.

action; ...

A sequence of zero or more actions separated by semicolons and enclosed in


curly braces.

Description
The for loop works similarly to the for loop in the C language. This for loop executes the initial-action
once, and then checks the bool-exp. If the bool-exp is TRUE, it executes the action block followed by
the step-action. It repeats this sequence in a loop for as long as bool-exp is TRUE.

Notes

You must enter an initial-action.


If you use a loop variable within a for loop, you must declare it before the loop (unlike the temporary
variable of type int automatically declared in a for from to loop).
Although this action is similar to a C-style for loop, keep in mind that the initial-action and step-action
must be e style actions. For example, the following syntax wont run:
for {i=0,j=0; i < 10; i += 1} //incorrect syntax

While the following syntax will run:


for {{i=0;j=0}; i < 10; i += 1} //correct syntax

Example
var i: int;
var j: int;
for {i = 0; i < 10; i += 1} do {
if i % 3 == 0 then {
continue;
};
j = j + i;
if j > 100 then {
break;
};
};

See Also

while on page 568

repeat until on page 570

for each in on page 572

Specman e Language Reference


1999-2015

580

Product Version 15.1


All Rights Reserved.

for each in set on page 575

for from to on page 577

Conditional Actions on page 561

File Iteration Actions on page 581

Actions for Controlling the Program Flow on page 584

9.3

File Iteration Actions

This section describes the following two loop constructs, which are used to manipulate general ASCII
files:

for each line in file on page 581

for each file matching on page 582

9.3.1

for each line in file

Purpose
Iterate a for loop over all lines in a text file

Category
Action

Syntax
for each [line] [(name)] in file file-name-exp [do] {action; ...}
Syntax Example
for each line in file "signals.dat" do {'(it)' = 1};
// Reads a list of signal names and
// assigns to each the value 1

Parameters
name

Variable referring to the current line in the file.

file-name-exp

A string expression that gives the name of a text file. The file can be
compressed.

Specman e Language Reference


1999-2015

581
.

Product Version 15.1


All Rights Reserved.

action; ...

A sequence of zero or more actions separated by semicolons and enclosed in


curly braces.

Description
Executes the action block for each line in the text file file-name.
Optionally, the text file can be compressed, in which case Specman decompresses the file before
retrieving the lines.
Inside the block, it (or optional name) refers to the current line (as string) without the final \n (the final
new line character, CR).

Example
This example reads each line of a file and prints the line if it is not blank. String matching is used to see
if the line is blank: l !~ "/^$/" means l does not match the beginning of a line, ^, followed
immediately by the end of a line, $.
for each line (l) in file "test.dat" {
// Print all the nonblank lines in the file
if l !~ "/^$/" then { print l; };
};

If the file cannot be opened, an error message similar to the following appears.
for each line in file "er_file" {print it};
*** Error: Cannot open input file 'er_file' for reading

See Also

for each file matching on page 582

Conditional Actions on page 561

Iterative Actions on page 568

Actions for Controlling the Program Flow on page 584

9.3.2

for each file matching

Purpose
Iterate a for loop over a group of files

Specman e Language Reference


1999-2015

582

Product Version 15.1


All Rights Reserved.

Category
Action

Syntax
for each file [(name)] matching file-name-exp [do] {action; ...}
Syntax Example
for each file matching "*.e" {out(it);}
//lists the e files in the current directory

Parameters
name

Variable referring to the current line in the file.

file-name-exp

A string expression giving a file name.

action; ...

A sequence of zero or more actions separated by semicolons and enclosed in


curly braces.

Description
For each file (in the file search path) whose name matches file-name-exp execute the action block. Inside
the block, it (or optional name) refers to the matching file name.

Example
for each file (f_name) matching "*.txt" do {
for each line in file f_name{
if it ~ "/error/" then {out(it);
};
};
};

See Also

for each line in file on page 581

Conditional Actions on page 561

Iterative Actions on page 568

Actions for Controlling the Program Flow on page 584

Specman e Language Reference


1999-2015

583
.

Product Version 15.1


All Rights Reserved.

9.4

Actions for Controlling the Program Flow

The actions described in this section are used to alter the flow of the program in places where the flow
would otherwise continue differently. The e language provides the following actions for controlling the
program flow:

break on page 584

continue on page 585

9.4.1

break

Purpose
Break the execution of a loop

Category
Action

Syntax
break
Syntax Example
break

Description
Breaks the execution of the nearest enclosing iterative action (for or while). When a break action is
encountered within a loop, the execution of actions within the loop is terminated, and the next action to
be executed is the first one following the loop.
You cannot place break actions outside the scope of a loop (the compiler will report an error).

Example
for each (p) in packet_list do {
// ... other code
if p.len == 0 then {
break; // Get out of this loop
};
// ... other code
Specman e Language Reference
1999-2015

584

Product Version 15.1


All Rights Reserved.

};

See Also

continue on page 585

Conditional Actions on page 561

Iterative Actions on page 568

File Iteration Actions on page 581

9.4.2

continue

Purpose
Stop executing the current loop iteration and start executing the next loop iteration

Category
Action

Syntax
continue
Syntax Example
continue

Description
Stops the execution of the nearest enclosing iteration of a for or a while loop, and continues with the
next iteration of the same loop. When a continue action is encountered within a loop, the current
iteration of the loop is aborted, and execution continues with the next iteration of the same loop.
You cannot place continue actions outside the scope of a loop (the compiler will report an error).

Example
for each (p) in packet_list do {
if p.len == 1 then {
continue;
// Go to next iteration, skip "print p"
};
print p;
Specman e Language Reference
1999-2015

585
.

Product Version 15.1


All Rights Reserved.

};

See Also

break on page 584

Conditional Actions on page 561

Iterative Actions on page 568

File Iteration Actions on page 581

Specman e Language Reference


1999-2015

586

Product Version 15.1


All Rights Reserved.

10

Checks and Error Handling

The e language has many constructs that check for errors in the DUT or add exception handling and
diagnostics to an e program. This chapter covers these topics:

Handling DUT Errors on page 587

Handling User Errors on page 606

Handling Programming Errors on page 614

See Also

Chapter 4 Specman Error Handling in Compiling, Linking, and Running Specman

10.1 Handling DUT Errors


There are several constructs you can use to perform data or protocol checks on the DUT and to specify
how you want to handle any errors that occur:

check that on page 588

dut_error() and dut_errorf() on page 591

dut_error_struct on page 594

set_check() on page 599

set_check_by_name() on page 602

Specman e Language Reference


1999-2015

587
.

Product Version 15.1


All Rights Reserved.

10.1.1

check that

Purpose
Perform a data comparison and performs a defined response depending on whether the result of the
check was TRUE or FALSE.

Category
Action

Syntax
check [[name] that] bool-exp [[then] true-block] [else dut-error-action]
Syntax Example
check_count(i:int) is {
check that i == expected_count else
dut_error("Bad i: ", i);
};

Note Keep in mind that check that, as with all actions, must be associated with a method. Checks are
also created implicitly from expect/assume struct members.

Parameters
name

Any legal e identifier.


When the argument name is used, the keyword that is mandatory.
For more information, see Using Named check Actions on page 590.

bool-exp

Boolean expression that performs a data comparison.

true-block

Code block to be performed if bool-exp resolves to TRUE.

dut-error-action

A dut_error() or dut_errorf() action to be performed if bool-exp resolves to


FALSE.
For syntax and more information, see dut_error() and dut_errorf() on page 591.

Specman e Language Reference


1999-2015

588

Product Version 15.1


All Rights Reserved.

Description
Performs a data comparison and, depending on the results, either performs the optional code block (if
TRUE) or prints a message (if FALSE). The following example,
check_hard_error() is {
check that 'top.hard_error'== 1 else
dut_error("Error-5 -- Hard error not asserted");
};

displays an error message like this one:


*** Dut error at time 0
Checked at line 4 in check2.e
In sys-@0.check_hard_error():
Error-5 -- Hard error not asserted
Will stop execution immediately (check effect is ERROR)
*** Error: A Dut error has occurred

Using check that allows you to:

Define a different response depending on whether the check result resovles to TRUE or FALSE.

Manipulate the response to failed checks with the set checks command.

Show which checks have failed with the show checks command.

Track the number of failed checks with predefined session fields.

Omitting the else Clause


If you omit the else dut_error clause, Specman uses the check that clause as the error message if the
check fails. For example,
check_a() is {
check that a < b;
};

displays an error message like this one:


*** Dut error at time 0
Checked at line 6 in check3.e
In sys-@0.check_a():
check that a < b
Will stop execution immediately (check effect is ERROR)
Specman e Language Reference
1999-2015

589
.

Product Version 15.1


All Rights Reserved.

*** Error: A Dut error has occurred

Example with a dut_error() Action Block


This example used the optional action block for dut_error(). The out() action expands the error
message.
check_count(i:int) is {
check that i == expected_count else
dut_error("Bad i: ", i) {
out("expected count was: ", expected_count);
};
};

Using Named check Actions


You can use the name argument to associate a unique name with a check action. Naming a check makes
it easy to refer to the check during Specman sessions (in both user and message output).
Check actions are members of the struct for which the context method is defined. If several check
actions in the context of the same struct (no matter whether they appear in the same method or in
different methods) use the same name, they are considered several layers of the same check.
Notes

It is not allowed to define a named check action in the context of a struct, if another check action
with the same name is already defined earlier in the context of its subtype. An attempt to do so leads
to a compile time error.
expect/assume struct members are other kinds of checks. They share the same namespace and their
rule_name arguments (if used) must be unique with regard to a named check action.

Example
extend bus_e {
expect bus_cycle_length is
@transmit_start => {[0..999]; transmit_end} @bus_clk;
check() is also {
check bus_cycle_length that num_of_cycles < 1000;
};
};

Specman e Language Reference


1999-2015

590

Product Version 15.1


All Rights Reserved.

Result
*** Error: Check 'bus_e.bus_cycle_length' was previously defined at line
11 in test.e
[Note that check actions and expects occupy the same struct name space]
at line 16 in test.e
check bus_cycle_length that num_of_cycles < 1000;

See Also

Chapter 4 Specman Error Handling in Compiling, Linking, and Running Specman

10.1.2

dut_error() and dut_errorf()

Purpose
Issue a DUT error message

Category
Action

Syntax
dut_error(message: exp, ...) [ action-block ]
dut_errorf(format: string, item: exp, ...) [ action-block ]
Syntax Example
if 'data_out' != 'data_in' then
{dut_error("DATA MISMATCH: Expected ", 'data_in')};

Parameters
message

format

String or an expression that can be converted to a string. The message expressions are
converted to strings, concatenated, and printed to the screen (and to the log file if it is
open).
A string expression containing a standard C formatting mask for each item. (See Format
String on page 1528 for more information.)

Specman e Language Reference


1999-2015

591
.

Product Version 15.1


All Rights Reserved.

item

A legal e expression:

action-block

String expressions must be enclosed in double quotes ("").


If the expression is a struct instance, the struct ID is printed.
If the expression is a list, an error is issued.

Optional actions to be executed when the dut_error() is triggered (in particular when it is
not ignored due to a check-effect configuration). Typically used for further output
processing. See set_check() on page 599 for information about the possible
check-effects.

Description
Specifies a DUT error message. This action is usually associated with an if action, a check that action,
or an expect struct member. If the Boolean expression in the associated action or struct member
evaluates to TRUE, then the error message string is displayed.
Calling dut_error() directly is exactly equivalent to:
check that FALSE else dut_error();

Note
When you call dut_error() directly (not within a check that or an expect), there is no way to see that a
check was successfully performed. session.check_ok is always FALSE after a direct call to
dut_error().

Example
<'
extend sys {
m() is {
if 'data_out' != 'data_in' then
{dut_error("DATA MISMATCH: Expected ", 'data_in')};
};
};
'>

Result
cmd-prompt> sys.m()
*** Dut error at time 0
Checked at line 4 in /tests/check6.e
In sys-@0.m():
Specman e Language Reference
1999-2015

592

Product Version 15.1


All Rights Reserved.

DATA MISMATCH: Expected 1


Will stop execution immediately (check effect is ERROR)
*** Error: A Dut error has occurred

Example with a dut_error() Action Block


This example used the optional action block for dut_error(). The out() action expands the error
message.
check_count(i:int) is {
check that i == expected_count else
dut_error("Bad i: ", i) {
out("expected count was: ", expected_count);
};
};
};

See Also

Specman Error Handling in Compiling, Linking, and Running Specman

Specman e Language Reference


1999-2015

593
.

Product Version 15.1


All Rights Reserved.

10.1.3

dut_error_struct

Purpose
Define DUT error response

Category
Predefined struct

Syntax
struct dut_error_struct {
get_check_name(): string;
get_action_block_text(): list of string;
get_message(): string;
source_struct(): any_struct;
source_location(): string;
source_struct_name(): string;
source_method_name(): string;
check_effect(): check_effect;
set_check_effect(effect:check_effect);
write();
pre_error() is empty;
};
Syntax Example
extend dut_error_struct {
write() is also {
if source_struct() is a XYZ_packet (p) then {
print p.parity_calc();
};
};
};

Specman e Language Reference


1999-2015

594

Product Version 15.1


All Rights Reserved.

Struct Members
get_check_name()

Returns the name of the check in which this dut_error resides. If there is
no check action, or if the check is unnamed, it returns an empty string.

get_action_block_text() Returns the additional text created by the optional action block . If this
dut_error has no action block, it returns an empty list.
get_message()

Returns the message that was defined by the temporal or data DUT
check and is printed by dut_error_struct.write().

source_struct()

Returns a reference to the struct where the temporal or data DUT check
is defined.

source_location()

Returns a string giving the line number and source module name, for
example, At line 13 in @checker.

source_struct_name()

Returns a string giving the name of the source struct, for example,
packet.

source_method_name() Returns a string giving the name of the method containing the DUT
data check, for example, done().
check_effect()

Returns the check effect of that DUT check, for example,


ERROR_AUTOMATIC.

set_check_effect()

Sets the check effect in this instance of the dut_error_struct. You can
call this method from pre_error() to change the check effect of selected
checks.

pre_error()

The first method that is called when a DUT error occurs, unless the
check effect is IGNORE. This method is defined as empty, unless
extended by the user. Extending this method lets you modify error
handling for a particular instance or set of instances of a DUT error.
For a description of the error handling procedure in detail, see How
Specman Handles Errors in Compiling, Linking, and Running Specman.

write()

The method that is called after dut_error_struct.pre_error() is called


when a DUT error happens. This method causes the DUT message to be
displayed, unless the check effect is IGNORE. You can extend this
method to perform additional actions.
For a description of the error handling procedure in detail, see How
Specman Handles Errors in Compiling, Linking, and Running Specman.

Description
The predefined struct dut_error_struct defines the DUT error response. To modify the error response,
extend either write() or pre_error().

Specman e Language Reference


1999-2015

595
.

Product Version 15.1


All Rights Reserved.

Only the write() and pre_error() methods are called directly by Specman, but you can use the other
fields and predefined methods of dut_error_struct when you extend write() or pre_error().

Note
Do not use dut_error_struct.write() to change the value of the check effect. Use pre_error() instead.

Example 1
The following code implements a parity checker using DUT error checks. dut_error_struct.write() has
been extended to print additional information.
<'
type XYZ_kind_type : [good, bad] ;
struct XYZ_packet {
kind : XYZ_kind_type ;
%addr : uint (bits : 2) ;
%len : uint (bits : 6) ;
%data [len] : list of byte ;
%parity : byte ;
parity_calc() : byte is {
result = addr | (len << 2) ;
for each (item) in data do {
result ^= item ;
};
};
parity_check(p: XYZ_packet) is {
p.kind = ('data' == p.parity_calc()) ? good : bad;
if (p.kind == good) then {
check that 'err' == 0 else
dut_error ("Err != 0 for good pkt");
}
else {
check that 'err' == 1 else
dut_error ("Err != 1 for bad pkt");
};
};
};
extend dut_error_struct {
write() is also {
if source_struct() is a XYZ_packet (p) then {
print p.parity_calc();
};
Specman e Language Reference
1999-2015

596

Product Version 15.1


All Rights Reserved.

};
};
extend sys {
packets[10]: list of XYZ_packet;
check_packets() is {
for each XYZ_packet (p) in packets {
p.parity_check(p);
};
};
setup() is also {
set_check("...Err...pkt...", ERROR_CONTINUE);
};
run() is also {
check_packets();
};
};
'>

Result
In this test, 9 DUT errors occur.
Specman > test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
------------------------------------------------------*** Dut error at time 0
Checked at line 24 in check8.e
In XYZ_packet-@0.parity_check():
Err != 1 for bad pkt
p.parity_calc() = 228
------------------------------------------------------Will continue execution (check effect is ERROR_CONTINUE)
...
No actual running requested.
Checking the test ...
Specman e Language Reference
1999-2015

597
.

Product Version 15.1


All Rights Reserved.

Checking is complete - 9 DUT errors, 0 DUT warnings.


Specman >

Example 2
This example extends Example 1, extending pre_error() so that no more than 3 parity errors will be
displayed.
<'
extend sys {
num_parity_errors: uint;
keep num_parity_errors == 0;
};
extend dut_error_struct {
pre_error() is also {
if source_struct() is a XYZ_packet then {
sys.num_parity_errors = sys.num_parity_errors +1;
if sys.num_parity_errors > 3 then {
set_check_effect(IGNORE);
};
};
};
};
'>

Result
Specman checking9> test
Doing setup ...
2 checks were modified.
Generating the test using seed 1...
Starting the test ...
Running the test ...

------------------------------------------------------*** Dut error at time 0


Checked at line 25 in @checking8
In XYZ_packet-@0.parity_check():
Err != 1 for bad pkt
p.parity_calc() = 228
------------------------------------------------------Will continue execution (check effect is ERROR_CONTINUE)
...
Specman e Language Reference
1999-2015

598

Product Version 15.1


All Rights Reserved.

No actual running requested.


Checking the test ...
Checking is complete - 3 DUT errors, 0 DUT warnings.
Specman checking9>

Example 3
This example shows how error messages can be handled within units. (See Units Overview on page 265
for a description of units and modular verification.)
To print some unit status information upon any error happening within a unit, you could extend
dut_error_struct.write() as shown below. The call to try_enclosing_unit() returns NULL if not called
from within a MIPS unit. If called from within a MIPS unit, the status of that MIPS unit is printed.
<'
extend dut_error_struct {
write() is also {
var MIPS:= source_struct().try_enclosing_unit(MIPS);
if MIPS != NULL then {
out("-- Status of ", MIPS.e_path(),
" at time of error: --");
MIPS.show_status();
};
};
};
'>

See Also

Specman Error Handling in Compiling, Linking, and Running Specman

Global Method print_stack_trace() on page 1149

10.1.4

set_check()

Purpose
Set check severity of check action or expect/assume struct member

Category
Predefined routine

Specman e Language Reference


1999-2015

599
.

Product Version 15.1


All Rights Reserved.

Syntax
set_check(static-match: string, check-effect: keyword, root_unit: any_unit=NULL, recursive:
bool=TRUE)
Syntax Example
<'
extend sys {
setup() is also {
set_check("...", WARNING);
};
};
'>

Parameters
static-match

A regular expression enclosed in double quotes. Only checks whose


message string matches this regular expression are modified. The match
string must use either the native Specman syntax or an AWK-like syntax.
See String Matching on page 99.
Note You must enclose AWK-like syntax in forward slashes, for
example, /Vio/. Also, the * character in native Specman syntax matches
only non-white characters. Use ... to match white or non-white characters.

check-effect is one of the following:


ERROR

Specman issues an error message, increases num_of_dut_errors, halts


the run immediately, and returns to the simulator prompt or exits.

ERROR_BREAK_RUN

Specman issues an error message, increases num_of_dut_errors, breaks


the run at the next cycle boundary and updates the simulation GUI with
the latest values, and returns to the simulator prompt or exits.

ERROR_AUTOMATIC

Specman issues an error message, increases num_of_dut_errors, breaks


the run at the next cycle boundary, and performs the end of test checking
and finalization of test data that is normally performed when stop_run() is
called, and returns to the simulator prompt or exits.

ERROR_CONTINUE

Specman issues an error message, increases num_of_dut_errors, and


continues execution.

WARNING

Specman issues a warning, increases num_of_dut_warnings and


continues execution.

Specman e Language Reference


1999-2015

600

Product Version 15.1


All Rights Reserved.

IGNORE

Specman issues no messages, does not increase num_of_dut_errors or


num_of_dut_warnings, and continues execution.

root_unit

Unit instance to which the new setting applies. By default, or if NULL is


passed, the setting applies globally to all units.

recursive

If TRUE (default), applies recursively to the subtree of the specified unit.


If FALSE, applies to the specified unit only. If root_unit is NULL, this
parameter has no effect.

Description
Sets the severity or the check effect of specific DUT checks, so that failing checks will produce errors or
warnings.
See How Specman Handles Errors in Compiling, Linking, and Running Specman for a discussion of how
these check effects can be used in interactive and batch mode.
Using the root_unit option, you can define different check effects for the same check depending on the
specific unit instance in the context of which the check is performed.

Note

This command affects only checks that are currently loaded into Specman.
e programming diagnostics defined with the warning(), error(), fatal(), and try() constructs are not
influenced by the set_check() predefined routine.
All DUT errors not set to ERROR_CONTINUE, WARNING or IGNORE stop simulation at the point
of error. If break on error is enabled, the Specman debugger is invoked automatically.
If the error occurs before the simulation has started, then ERROR_BREAK_RUN and
ERROR_AUTOMATIC will have the same behavior as ERROR.
If a DUT checks check effect is ERROR and a configure run -error_command option is specified,
the error command actions are also executed.
If a DUT checks check effect is ERROR-BREAK-RUN, the tick is normally completed so execution
can continue. On the other hand, if a DUT checks check effect is ERROR (and therefore, the run
halts immediately), it is recommended to NOT continue the run because it may produce unexpected
behavior.

Example
Loading the following extension changes the check effect of all currently defined checks to WARNING
during the setup phase of test.

Specman e Language Reference


1999-2015

601
.

Product Version 15.1


All Rights Reserved.

<'
extend sys {
setup() is also {
set_check("...", WARNING);
};
};
'>

Result
cmd-prompt> setup
Doing setup ...
5 checks were modified.
cmd-prompt> show checks

Checks information:
0. check @sn_cover in simulator.error_from_simulator (WARNING)
count=0 Error from simulator: ...
1. check @sn_cover_misc in covers.cover_dut_error (WARNING)
count=0 Illegal value for cover item ...
2. check @sn_coverage in scheduler.handle_event (WARNING)
count=0 event ... which has a global cover group, occurred
more than once
3. check @check8 in XYZ_packet.parity_check (WARNING) count=0
Err != 0 for good pkt
4. check @check8 in XYZ_packet.parity_check (WARNING) count=0
Err != 1 for bad pkt

See Also

How Specman Handles Errors in Compiling, Linking, and Running Specman

set checks in the Specman Command Reference

configure run in the Specman Command Reference

10.1.5

set_check_by_name()

Purpose
Set check severity of named check action or expect/assume struct member

Specman e Language Reference


1999-2015

602

Product Version 15.1


All Rights Reserved.

Category
Predefined routine

Syntax
set_check_by_name(struct-name: string, check-name: string, check-effect: keyword, root_unit:
any_unit=NULL, recursive: bool=TRUE, all_layers: bool=FALSE)
Syntax Example
<'
extend sys {
setup() is also {
set_check_by_name("packet", "legal_address", ERROR;
set_check_by_name("vr_xbus::*", "*address", WARNING;
};
};
'>

Parameters
struct-name

The struct type name enclosed in double quotes. Wildcard are allowed.

check-name

A legal e name enclosed in double quotes.

check-effect is one of the following:


ERROR

Specman issues an error message, increases num_of_dut_errors, halts


the run immediately, and returns to the simulator prompt or exits.

ERROR_BREAK_RUN

Specman issues an error message, increases num_of_dut_errors, breaks


the run at the next cycle boundary and updates the simulation GUI with
the latest values, and returns to the simulator prompt or exits.

ERROR_AUTOMATIC

Specman issues an error message, increases num_of_dut_errors, breaks


the run at the next cycle boundary, and performs the end of test checking
and finalization of test data that is normally performed when stop_run() is
called, and returns to the simulator prompt or exits.

ERROR_CONTINUE

Specman issues an error message, increases num_of_dut_errors, and


continues execution.

WARNING

Specman issues a warning, increases num_of_dut_warnings and


continues execution.

Specman e Language Reference


1999-2015

603
.

Product Version 15.1


All Rights Reserved.

IGNORE

Specman issues no messages, does not increase num_of_dut_errors or


num_of_dut_warnings, and continues execution.

root_unit

Unit instance to which the new setting applies. By default, or if NULL is


passed, the setting applies globally to all units.

recursive

If TRUE (default), applies recursively to the subtree of the specified unit.


If FALSE, applies to the specified unit only. If root_unit is NULL, this
parameter has no effect.

all_layers

If FALSE (default), applies only to check layers that reside directly under
the specified struct(s). If TRUE, applies to all layers of check(s) whose
first declaring layer resides under the specified struct(s).

Description
Sets the severity or the check effect of specific named DUT checks, so that failing checks will produce
errors or warnings.
See How Specman Handles Errors in Compiling, Linking, and Running Specman for a discussion of how
these check effects can be used in interactive and batch mode.
Using the root_unit option, you can define different check effects for the same check depending on the
specific unit instance in the context of which the check is performed.

Note

This command affects only checks that are currently loaded into Specman having the specified
check-name.
e programming diagnostics defined with the warning(), error(), fatal(), and try() constructs are not
influenced by the set_check_by_name() predefined routine.
All DUT errors not set to ERROR_CONTINUE, WARNING or IGNORE stop simulation at the point
of error. If break on error is enabled, the Specman debugger is invoked automatically.
If the error occurs before the simulation has started, then ERROR_BREAK_RUN and
ERROR_AUTOMATIC will have the same behavior as ERROR.
If a DUT checks check effect is ERROR and a configure run -error_command option is specified,
the error command actions are also executed.
If a DUT checks check effect is ERROR-BREAK-RUN, the tick is normally completed so execution
can continue. On the other hand, if a DUT checks check effect is ERROR (and therefore, the run
halts immediately), it is recommended to NOT continue the run because it may produce unexpected
behavior.

Specman e Language Reference


1999-2015

604

Product Version 15.1


All Rights Reserved.

Example 1

Set Check by Name in When Subtype

If the check is defined in the when subtype, not the base type, you must pass the name of the when
subtype to the set_check_by_name() routine.
<'
type length_t: [LONG,SHORT];
struct packet_s {
%header: byte;
%data: uint;
len: length_t;
actual_count: uint(bits:4);
when LONG packet_s {
%more_data: uint;
chk_cnt(u:uint) is {
check check_count that actual_count == u else
dut_error("Actual count is: ", actual_count,
"
Expected count is: ", u);
};
};
};
extend sys {
packets[5]: list of packet_s;
expected_count: uint(bits:4);
setup() is also {
set_check_by_name("LONG packet_s", "check_count", WARNING);
};
run() is also {
var expected: uint;
expected = 15;
for each (p) in packets {
if p is a LONG packet_s {p.as_a(LONG packet_s).chk_cnt(expected)};
};
};
};
'>

See Also

How Specman Handles Errors in Compiling, Linking, and Running Specman

Specman e Language Reference


1999-2015

605
.

Product Version 15.1


All Rights Reserved.

set checks in the Specman Command Reference

configure run in the Specman Command Reference

10.2 Handling User Errors


The e language has several constructs that help you handle user errors, such as file I/O errors or semantic
errors. This section describes the constructs used for handling these kinds of errors:

warning() on page 606, which issues a warning message when a given error occurs.
error() on page 607, which issues an error message and exits to the Specman prompt when a given

error is detected.

fatal() on page 609, which issues an error message and exits to the UNIX prompt when a given error

is detected.

try on page 612, which defines an alternative response for fixing or bypassing an error.

Note Errors handled by these constructs do not increase the session.num_of_dut_errors and
session.num_of_dut_warnings fields that are used to track DUT errors. In addition, the error responses
defined with these constructs are not displayed by the show checks command or influenced by the set
checks command or modifications to the dut_error_struct.write() method.

See Also

configure run in the Specman Command Reference

10.2.1

warning()

Purpose
Issue a warning message

Category
Action

Syntax
warning(message: string, ...)
Syntax Example
warning("len exceeds 50");

Specman e Language Reference


1999-2015

606

Product Version 15.1


All Rights Reserved.

Parameter
message

String or an expression that can be converted to a string. When the warning


action is executed, the message expressions are converted to strings,
concatenated, and printed to the screen.

Description
Issues the specified warning error message. Does not halt the methods being currently run.

Example
check_size() is {
if (pkt.size != LARGE) {
warning("packet size is ", pkt.size);
};
};

Result
*** Warning: packet size is SMALL

See Also

error() on page 607

fatal() on page 609

try on page 612

configure run in the Specman Command Reference

10.2.2

error()

Purpose
Issue an error message

Category
Action

Specman e Language Reference


1999-2015

607
.

Product Version 15.1


All Rights Reserved.

Syntax
error(message: string, ...)[ action-block]
Syntax Example
check_size() is {
if (pkt.size != LARGE) {
error("packet size is ", pkt.size);
};
};

Parameter
message

String or an expression that can be converted to a string. When the error action is
executed, the message expressions are converted to strings, concatenated, and
printed to the screen.

action-block

Optional actions to be executed when the error() is triggered (typically used for
further output processing).

Description
Issues the specified error message, halts all methods being currently run, and returns to the Specman
prompt. The only exception to this is if the error action appears inside the first action block given in a
try action. In that case, Specman jumps to the else action block within the try action and continues
running.

Example
<'
type size : [SMALL, LARGE];
struct packet {
size;
};
extend sys {
pkt: packet;
check_size() is {
if (pkt.size != LARGE) {
error("packet size is ", pkt.size);
};
};
};
Specman e Language Reference
1999-2015

608

Product Version 15.1


All Rights Reserved.

'>

Result
*** Error: packet size is SMALL
at line 13 in @pkt_test
error("packet size is ", pkt.size);

(assuming that the source file is called pkt_test.e, and the error() action resides in it at line 13)

Example with an error() Action Block


This example uses the optional action block for error(). The out() action expands the error message.
check_count(i:int) is {
check that i == expected_count else
error("Bad i: ", i) {
out("expected count was: ", expected_count);
};
};
};

See Also

warning() on page 606

fatal() on page 609

try on page 612

configure run in the Specman Command Reference

10.2.3

fatal()

Purpose
Issue error message and exit Specman to return to the UNIX prompt

Category
Action

Syntax
fatal(message: string, ...)
Specman e Language Reference
1999-2015

609
.

Product Version 15.1


All Rights Reserved.

Syntax Example
fatal("Run-time error - exiting Specman");

Parameter
message

String or an expression that can be converted to a string. When the fatal()


action is executed, the message expressions are converted to strings,
concatenated, and printed to the screen.

Description
Issues the specified error message, halts all activity, exits Specman immediately, and returns to the
UNIX prompt. (If you are working in Specview, a dialog box appears before you are returned to the
UNIX prompt.)
fatal() returns a non-zero status to the UNIX shell.

Using fatal with config run error_command


You can use fatal() with the -error_command option of the config run command to automatically stop
simulation completely when an error occurs. For example, the following code creates the
error_actions() method, which is called when any error occurs:
extend sys {
setup() is also {
set_config(run, error_command, "sys.error_actions()");
};
};

And the following code defines sys.error-actions() to exit Specman with the fatal() action when an
error occurs:
extend sys {
error_actions() is {
-- .. Maybe perform other error actions here
fatal("Run-time error - exiting Specman");
};
};

Specman e Language Reference


1999-2015

610

Product Version 15.1


All Rights Reserved.

Example
The following code shows the use of warning(), error(), fatal(), and try. The code is intended to open
a log file. If the log file cannot be opened, the simulation issues a warning and tries to open a temporary
log file. If the temporary log file cannot be opened and if the simulation is in batch, it issues an error
message and exits to the UNIX prompt. If the simulation is interactive, it issues an error message only.
open_checking_log_file(file_name:string) is {
try {
var my_file :file = files.open(file_name, "w",
"Log file");
} else {
warning("Could not open ", file_name,
"; opening temporary log file sim.log");
try {
var my_file :file = files.open("sim.log", "w",
"Temp Log file");
} else {
close_stimulus_log_files();
if interactive == FALSE {
fatal("Could not open temp file sim.log.\n\n",
"Please check write permissions on current",
" directory, sim.log, and ", file_name,
".\n\nError level is ", error_level, ".");
} else {
error("Could not open temp file sim.log.\n\n",
"Please check write permissions on current",
" directory, sim.log, and ", file_name,
".\n\nError level is ", error_level, ".");
};
};
};
};

See Also

warning() on page 606

error() on page 607

try on page 612

configure run in the Specman Command Reference

Specman e Language Reference


1999-2015

611
.

Product Version 15.1


All Rights Reserved.

10.2.4

try

Purpose
Define an alternative response for fixing or bypassing an error

Category
Action

Syntax
try {action; ...} [else {action; ...}]
Syntax Example
try {
var my_file :file = files.open(file_name, "w",
"Log file");
} else {
warning("Could not open ", file_name,
"; opening temporary log file sim.log");
};

Parameters
action; ...

A series of zero or more actions enclosed in curly braces and separated by semicolons.
The first action block (following try) cannot include the fatal() action. Subsequent
action blocks (following else) can.

Description
Executes the action block following try. If the try action block causes an error, execution continues (no
error message is printed). Thus, try lets you define actions for the system to try to execute, without
running the risk of execution stopping because of an error.
When an error occurs during the try action block:

If defined, the else action block is executed immediately following the error.
After the else action block (if any) is executed, normal execution continues from the first action
following the try block.

Specman e Language Reference


1999-2015

612

Product Version 15.1


All Rights Reserved.

Note If a fatal error is encountered during execution of the try action, then Specman exits
immediately. For all other errors, howeverincluding Specman errors such as null pointer access or
segmentation violation errorsexecution continues normally after the error is encountered.

Example
The following code example shows the use of warning(), error(), fatal(), and try. The code is intended
to open a log file. If the log file cannot be opened, the simulation issues a warning and tries to open a
temporary log file. If the temporary log file cannot be opened and if the simulation is in batch, it issues
an error message and exits to the UNIX prompt. If the simulation is interactive, it issues an error
message only.
open_checking_log_file(file_name:string) is {
try {
var my_file :file = files.open(file_name, "w",
"Log file");
} else {
warning("Could not open ", file_name,
"; opening temporary log file sim.log");
try {
var my_file :file = files.open("sim.log", "w",
"Temp Log file");
} else {
close_stimulus_log_files();
if interactive == FALSE {
fatal("Could not open temp file sim.log.\n\n",
"Please check write permissions on current",
" directory, sim.log, and ", file_name,
".\n\nError level is ", error_level, ".");
} else {
error("Could not open temp file sim.log.\n\n",
"Please check write permissions on current",
" directory, sim.log, and ", file_name,
".\n\nError level is ", error_level, ".");
};
};
};
};

See Also

warning() on page 606

error() on page 607

fatal() on page 609

configure run in the Specman Command Reference

Specman e Language Reference


1999-2015

613
.

Product Version 15.1


All Rights Reserved.

10.3 Handling Programming Errors


The e language has a special construct, the assert action, to help you handle programming errors, such
as internal contradictions or invalid parameters.

10.3.1

assert

Purpose
Check the e code for correct behavior

Category
Action

Syntax
assert bool-exp [else error(message: string, ...)]
Syntax Example
assert a < 20;

Parameters
bool-exp

Boolean expression that checks the behavior of the code.

message

String or an expression that can be converted to a string. If the bool-exp is FALSE,


the message expressions are converted to strings, concatenated, and printed to the
screen (and to the log file if it is open).

Description
Checks the e code for correct behavior. Use this action to catch coding errors. When an assert fails, it
prints the specified error message plus the line number and name of the file in which the error occurred.
If you omit the else error clause, assert prints a global error message.

Note
When an error is encountered, assert stops the method being executed.

Specman e Language Reference


1999-2015

614

Product Version 15.1


All Rights Reserved.

Example
<'
extend sys {
a: uint;
m() is {
assert a < 20 else error("The value of a is ", a);
out("Should never get here if a is 20 or more");
};
};
'>

Result
*** Error: Assertion failed (a programming error):
The value of a is 1840385568
In 'sys.m()' at line 6 in check22.e

See Also

warning() on page 606

error() on page 607

fatal() on page 609

try on page 612

configure run in the Specman Command Reference

Specman e Language Reference


1999-2015

615
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

616

Product Version 15.1


All Rights Reserved.

11

Generation Constraints

This chapter describes the e language constructs used to define constraints. It contains the following
sections:

Defining Constraints on page 617

Initiating Generation On the Fly on page 652

Using Procedural Code During Generation on page 656

See Also

Debugging e Generation Constraints

Specman Generation User Guide

Specman Pgen User Guide

11.1 Defining Constraints


This section contains the following:

constraint-def and bool-constraint-def on page 618

keep on page 620

Compound Constraint Block on page 623

for each on page 625

type ...is a on page 629

struct-list.is_all_iterations() on page 635

soft... select on page 637

gen-item.reset_soft() on page 644

name is [only] on page 646

Specman e Language Reference


1999-2015

617
.

Product Version 15.1


All Rights Reserved.

read_only() on page 649

Unidirectional Constraint Operators on page 650

See Also

gen...keeping on page 653

do on page 933

do_and_grab on page 936

Real Number Generation with the Specman Generator in Specman Generation User Guide

Real Number Generation with Pgen in Specman Pgen User Guide

11.1.1

constraint-def and bool-constraint-def

The syntax descriptions in this chapter include the terms constraint-def and bool-constraint-def to
specify the constraint definitions allowed in keep constructs. The two terms differ in terms of the
content that is allowed for each. They are defined in the following sections:

constraint-def on page 618

bool-constraint-def on page 619

See Also

keep on page 620

11.1.1.1 constraint-def
A constraint-def can consist of any of the following:

A bool-constraint-def (). For example:


keep kind != tx or len == 16;

For more information, see bool-constraint-def on page 619.

A compound constraint block. For example:


keep {
kind != tx;
len == 16;
};

For more information, see Compound Constraint Block on page 623.


Specman e Language Reference
1999-2015

618

Product Version 15.1


All Rights Reserved.

A for each list constraint. For example:


keep for each (p) in pkl {
soft p.protocol in [atm, eth];
};

For more information, see for each on page 625.

A type constraint. For example:


keep type f.p1 == p1;
keep for each in lf {
type it is a B S1;
};

For more information, see type ...is a on page 629.

An is_all_iterations() constraint. For example:


keep packets.is_all_iterations(.kind,.protocol);

For more information, see struct-list.is_all_iterations() on page 635.

A soft ... select constraint, constraining the distribution of values. For example:
keep soft me.opcode == select {
30: ADD;
20: ADDI;
10: [SUB, SUBI];
};

For more information, see soft... select on page 637.

gen-item.reset_soft() constraint, which end the evaluation of soft constraints for a field. For example:
keep c.reset_soft(); //removes the previous soft constraint on c

For more information, see gen-item.reset_soft() on page 644.


Any legal e operator can be used in a constraint-def, including calls to predefined or user-defined
methods. However, some operators are treated as unidirectional. For a list of the unidirectional
operators, see Unidirectional Constraint Operators on page 650.

11.1.1.2 bool-constraint-def
A bool-constraint-def is a Boolean expression that returns either TRUE or FALSE when evaluated at run
time and describes the legal values for generatable items or constrains the relation of one generatable
item to other generatable items.
Boolean constraint definitions can define either hard constraints or soft constraints:

Specman e Language Reference


1999-2015

619
.

Product Version 15.1


All Rights Reserved.

Hard constraints must be satisfied whenever the item is generated. When a contradicting set of
constraints occur, a contradiction error is issued.
Soft constraints are identified with the keyword soft.

When a hard constraint contradicts a soft constraint, the hard constraint is applied.
When two soft constraints contradict each other, the one that is loaded last into Specman is the
one that is applied.
No warning is issued when a soft constraint is overridden.

You can use soft constraints, for example, to set default values that can be overridden as necessary
by hard constraints.
Following is the syntax for a soft constraint:
soft bool-constraint-def
Notes

The soft keyword can be applied to Boolean constraint definitions only. You cannot, for example
define a gen-item.reset_soft() constraint as itself a soft constraint.
Note

The only other use of the soft keyword is as part of the soft... select operator.

For information on Pgen limitations on the placement of the soft keyword in compound Boolean
expressions, see Soft Constraints in the Specman Pgen User Guide.

11.1.2

keep

Purpose
Define a constraint

Category
Struct member

Syntax
keep [name is [only]] constraint-def
Syntax Examples
keep kind != tx or len == 16;
keep soft legal == TRUE;
Specman e Language Reference
1999-2015

620

Product Version 15.1


All Rights Reserved.

Parameters
name is [only]

constraint-def

Defines a name for the constraint. For more information about this syntax
and why you might want to name this constraint, see name is [only] on
page 646.
A constraint definition. For more information, see constraint-def on page
618.

Description
States restrictions on the values generated for fields in the struct or the struct subtree, or describes
required relationships between field values and other items in the struct or its subtree.
If the keep constraint appears under a when construct, the constraint is considered only if the when
condition is true.

Example 1
This example describes a required relationship between two fields, kind and len. If the current pkt
is of kind tx, then len must be 16.
struct pkt {
kind: [tx, rx];
len: uint;
keep kind == tx => len == 16;
};

Example 2
Here is the same example, except that the constraint on kind is soft.
struct pkt {
kind: [tx, rx];
len: uint;
keep soft kind == tx => len == 16;
};

Example 3
This example shows a required relationship between two fields, kind and len, using a local variable,
p, to represent pckt instances of kind tx:
struct pckt {
Specman e Language Reference
1999-2015

621
.

Product Version 15.1


All Rights Reserved.

kind: [tx, rx];


len: uint;
};
struct top {
packet: pckt;
keep packet.kind == tx => packet.len in [128..255];
};

Example 4
This example shows the use of a when subtype.
struct pkt {
kind: [tx, rx];
len: uint;
when tx pkt {
keep len == 16;
};
};

Example 5
This example shows how to call the list.is_a_permutation() method to constrain a list to have a random
permutation of items from another list. In this example, l_1 and l_2 will have exactly the same
elements. The elements will not necessarily appear in the same order.
struct astr {
l_1: list of int;
l_2: list of int;
keep l_2.is_a_permutation(l_1);
};

Example 6
This example shows a constraint on a single list item (data[0]) and the use of path names to identify
the item to be constrained.
type transaction_kind: [good, bad];
struct transaction {
kind: transaction_kind;
address: uint;
length: uint;
data: list of byte;
Specman e Language Reference
1999-2015

622

Product Version 15.1


All Rights Reserved.

};
extend transaction {
keep length < 24;
keep data[0] == 0x9a;
keep address in [0x100..0x200];
keep me.kind == good;
};
extend sys {
t: transaction;
keep me.t.length != 0;
};

See Also

constraint-def and bool-constraint-def on page 618

Compound Constraint Block on page 623

for each on page 625

type ...is a on page 629

struct-list.is_all_iterations() on page 635

soft... select on page 637

gen-item.reset_soft() on page 644

Initiating Generation On the Fly on page 652

Using Procedural Code During Generation on page 656

When Subtype Dependencies in the Specman Generation User Guide

11.1.3

Compound Constraint Block

Purpose
Define a constraint block

Category
Constraint definition

Specman e Language Reference


1999-2015

623
.

Product Version 15.1


All Rights Reserved.

Syntax
[all of] {constraint-def; ...}
bool-constraint-def => [all of] {constraint-def; ...}
Syntax Example
keep all of {
kind != tx;
len == 16;
};

Parameters
constraint-def

A constraint definition. For more information, see constraint-def on page


618.

bool-constraint-def

A Boolean constraint definition. For more information, see


bool-constraint-def on page 619.

Description
A compound keep constraint block is exactly equivalent to a keep constraint for each constraint
definition in the block. For example, the following constraint block
keep {
kind != tx;
len == 16;
};

is exactly equivalent to
keep kind != tx;
keep len == 16;

Note that the all of keywords are optional.

Example 1
This example shows a keep constraint in which the second constraint is compound:
type transaction_kind: [VERSION1, VERSION2, VERSION3];
struct transaction {
kind: transaction_kind;
address: uint;
length: uint;
Specman e Language Reference
1999-2015

624

Product Version 15.1


All Rights Reserved.

data: list of byte;


keep kind in [VERSION1, VERSION2] => {
length < 24;
data[0] == 0x9a;
address in [0x100..0x200];
};
};

See Also

keep on page 620

11.1.4

for each

Purpose
Constrain list items

Category
Constraint definition

Syntax
for each [(item-name)]
[using [index (index-name)] [prev (prev-name)]]
in gen-list {constraint-def | nested-for-each; ...}
Syntax Example
keep for each (p) in pkl {
soft p.protocol in [atm, eth];
};

Parameters
item-name

An optional name used as a local variable referring to the current item in the
list. The default is it.

Specman e Language Reference


1999-2015

625
.

Product Version 15.1


All Rights Reserved.

index-name

An optional name referring to index of the current item in the list. The default is
index.

prev-name

An optional name referring to the previous item in the list. The default is prev.

gen-list

A generatable path that results in a list.

constraint-def

A constraint definition. For more information, see constraint-def on page 618.

bool-constraint-def

A Boolean constraint definition. For more information, see bool-constraint-def


on page 619.

nested-for-each

A nested for each block, with the same syntax as the enclosing for each block,
except that keep is omitted.

Description
Defines a value constraint on multiple list items.

Notes

Each constraint definition in the for each must refer to the list item (it).
(If you are using Pgen, items whose pathname does not start with it can only be sampled; their
generated values cannot be constrained.)

Keep in mind that, in nested for each constraints, the default names it, prev, and index refer to items
in the inner-most for each loop.
If a for each constraint is contained in a gen ... keeping action, you must name the iterated variable.
See Example 3 on page 655 for more information.

In the following example, the keep for each in dat constraint in the pstr struct constrains all the dat
fields to be less than 64. Note that referring to the list items in the Boolean constraint definition it < 64
as dat[index] rather than it generates an error.
struct pstr {
dat: list of uint;
keep for each in dat {
it < 64;
};
};

Example 1
In this example, a soft constraint is defined in the constraint block:
Specman e Language Reference
1999-2015

626

Product Version 15.1


All Rights Reserved.

extend sys {
packets: list of packet;
keep for each in me.packets {
soft .len == 2k;
.kind != tx;
};
};

Example 2
In this example, we demonstrate how to enforce all-different constraint without using a
List-Pseudo-Method. using index () is used to enable the constraint under a nested keep-for-each to
access the two different indices of the keep-for-each.
extend sys {
l : list of uint;
keep for each (itm1) using index (i1) in l {
for each (itm2) using index (i2) in l {
i1 < i2 => itm1 != itm2;
};
};
};

Example 3
The following example illustrates the use of keep for each on a multi-dimensional list, using a nested
for each block:
<'
struct my_struct {
my_array[5][5] : list of list of uint;
keep for each (row) in my_array {
for each in row {it in [0..99]};
};
};
extend sys {
my_struct;
};
'>

Example 4
The following example shows the use of index in a nested for each block. The x field receives the
value of the outer index and each byte of payload receives the value of the inner index.

Specman e Language Reference


1999-2015

627
.

Product Version 15.1


All Rights Reserved.

struct packet {
x: int;
%payload: list of byte;
keep payload.size() == 10;
};
extend sys {
packets: list of packet;
keep packets.size() == 5;
keep for each (p) in packets {
p.x == index;
for each in p.payload {
it == index;
};
};
post_generate() is also {
for i from 0 to 4 {
print packets[i].x;
print packets[i].payload;
};
};
};

Results
Generating the test using seed 1...
packets[i].x = 0
packets[i].payload = (10 items, dec):
9
8
7
6
5
4

.0

packets[i].x = 1
packets[i].payload = (10 items, dec):
9
8
7
6
5
4

.0

packets[i].x = 2
packets[i].payload = (10 items, dec):
9
8
7
6
5
4

.0

packets[i].x = 3
packets[i].payload = (10 items, dec):
9
8
7
6
5
4

.0

packets[i].x = 4
packets[i].payload = (10 items, dec):
9
8
7
6
5
4

.0

Specman e Language Reference


1999-2015

628

Product Version 15.1


All Rights Reserved.

See Also

keep on page 620

11.1.5

type ...is a

Purpose
Refine the type of a field to one of its subtypes for the specified context

Category
Constraint definition

Syntax
type [me.]field-name is a type
type [me.]field-name.property-name == [me.]my-property-name
keep for each [(item-name)] in list-field-name {
...
type item-name is a type;
...
}
keep for each [(item-name)] in list-field-name {
...
type item-name.property-name == [me.]my-property-name;
...
}
Syntax Example
keep type f.p1 == p1;
keep for each in lf {
type it is a B S1;
};

Parameters
field-name

The name of a struct field in the enclosing struct.

type

The name of an enumerated or Boolean type.

Specman e Language Reference


1999-2015

629
.

Product Version 15.1


All Rights Reserved.

property-name

The name of an enumerated or Boolean field.

my-property-name

The name of a field of the same type as [child-]property-name.

item-name

An optional name used as a local variable referring to the current item in


the list. The default is it.

list-field-name

The name of a list field in the enclosing struct.

Description
You can put a type constraint on either:

A field of a struct type

A list field of a struct type

The declaration is similar to a regular constraint inside a keep struct member, or, in the list case, inside
a keep for each construct, with the type keyword prefixing the expression.
The type keyword is a constraint modifier syntactically analogous to soft. However, unlike soft, it can
modify only specific constraint definitions and can appear only in restricted contexts.
The type correlation can be constant or, when the correlated types are when subtypes, variable. The
former case is expressed using the is a operator. In the latter case, the determinant property (the when
determinant) of the referenced struct is equated to a determinant property of the same type in the
declaring struct type.
Typically, the static type of a field-access expression is determined according to the type of the field as
it was initially declared in the struct type of instance-expression (or in one of its supertypes). Type
constraints tying the static type of instance-expression with a subtype of the fields declared type can
change this rule.
If the context in which the field-access occurs requires the subtype, the field-access is automatically
down-cast. In this case a runtime check is added to ensure that the casting is justified, and an error is
issued if it is not. The runtime check involves a minor overhead, not more than that required by the
as_a() operator.

Type Constraints and like Subtypes


Type constraints work just as well for like subtypes of the declared type of the field. They apply to the
two is a forms of the keep type struct member.

Specman e Language Reference


1999-2015

630

Product Version 15.1


All Rights Reserved.

Notes

Type constraints with like subtypes cannot make the actual like type of a generated field dependent
on a when determinant. In other words, they may not figure under a when subtype if they affect a
field not declared in the same subtype. They are flagged as errors at compile time.
Using type constraints with like subtypes is not supported for the Pgen generator. Pgen treats such
constraints as if there were no type modifier, thus resulting in a contradiction at generation time.

The following simplistic code illustrates the effect of like narrowing type constraint in contrast to a
regular constraint, and the restriction described above:
struct dog {
};
struct poodle like dog {
};
struct person {
my_pet: dog;
};
struct child like person {
keep my_pet is a poodle; // constraint is flagged as
// having no generatable elements at compile time
// and ignored at generation time
keep type my_pet is a poodle; // constraint is enforced
size: [SMALL, BIG];
when SMALL child {
keep type my_pet is a poodle; // error - cannot make
// like narrowing depend on when determinant
my_other_pet: dog;
keep type my_other_pet is a poodle; // constraint is enforced
};
};

Note

Without the type modifier, keep my_pet is a poodle is non-generatable. (As described in
Table 11-2 on page 650, is a on a like subtype is unidirectional unless the type modifier is used.)

Transitive Downcasting
Access of struct members under type constraint can be transitive.

Specman e Language Reference


1999-2015

631
.

Product Version 15.1


All Rights Reserved.

If the field is under a type constraint, and the type defined by this constraint also has a type constraint on
some of its fields (and this type has constraints on some its fields ...), then an expression with a path of
more than one field access in a row allows automatic downcasting where required.
For example:
struct person { };
struct child like person {
school_grade: int;
my_pet: dog;
keep type my_pet is a poodle;
};

// second level of type constraint

struct dog { };
struct poodle like dog {
color: [black,white];
};
extend sys {
p: person;
keep type p is a child;
run() is also {
print p.school_grade;
print p.my_pet.color;
};
};

// first level of type constraint


// one level
// two levels

Rules for Using Type Constraints

Operators other than == and is a are not allowed.


For example, is only is not allowed, and operators like the following are not allowed:
keep type TRUE => engine is a FORD engine; // not allowed

The for each clause must occur immediately after keep.


For example, the following is not allowed:
keep my_doors.size() > 4 => for each in my_doors { // not allowed
type it is a small door;
}

Type constraints can equate only constant fields, so the const keyword must appear in the declaration
of fields involved in equality constraints.
Type constraints in general affect code from that point onwards. This includes type constraints that
appear inside a for each clause, in which case other expressions in the same scope after the declaration
(but not before it) can assume automatic casting.

Specman e Language Reference


1999-2015

632

Product Version 15.1


All Rights Reserved.

Type constraints cannot appear inside a gen action.

The soft keyword cannot be used with type constraints.

Example 1
This examples illustrates two of the four forms of allowed syntax.
<'
type property_t: [A, B, C];
struct S1 {
const p1: property_t;
};
struct S2 {
const p1: property_t;
f: S1;
lf: list of S1;
keep type f.p1 == p1;
keep for each in lf {
type it is a B S1;
};
};
extend sys {
my_S2: S2;
};
'>

Example 2
Here is a simple case where two struct types have a fixed correlation between their when subtypes:
type firm: [HONDA, FORD, MERCEDES];
struct engine {
const manufacturer: firm;
};
struct car {
const manufacturer: firm;
my_engine: engine;
// this constraint declares subtype correlation
keep type my_engine.manufacturer == manufacturer;
};

Specman e Language Reference


1999-2015

633
.

Product Version 15.1


All Rights Reserved.

Now consider the following code:


extend FORD engine {
change_plugs() is {
//...
};
};
extend FORD car {
fix() is {
my_engine.change_plugs();
};
};

Even though in the context of method fix(), the field my_engine is in fact of type FORD engine (due
to the generation constraint), a compile time error is issued on the call to change_plugs(). To fix it, you
have to use the as_a() operator.
By adding the type modifier to the constraint definition above, for example:
keep type my_engine.manufacturer == manufacturer;

the field-access in method fix() is automatically cast to FORD engine and passes static type checks.

Example 3
The following simplistic code illustrates the use of type constraints on like subtypes:
struct dog {
};
struct poodle like dog {
};
struct person {
my_pet: dog;
};
struct child like person {
keep my_pet is a poodle; // constraint is flagged as
// having no generatable elements at compile time
// and ignored at generation time
keep type my_pet is a poodle; // constraint is enforced
size: [SMALL, BIG];
when SMALL child {
Specman e Language Reference
1999-2015

634

Product Version 15.1


All Rights Reserved.

keep type my_pet is a poodle; // error - cannot make


// like narrowing depend on when determinant
my_other_pet: dog;
keep type my_other_pet is a poodle; // constraint is
// enforced
};
};

See Also

keep on page 620

Defining Type Constraints in the Specman Generation User Guide

11.1.6

struct-list.is_all_iterations()

Purpose
Cause a list of struct to have all iterations of one or more fields

Category
Constraint-definition list method

Syntax
struct-list.is_all_iterations(.field-name: exp, ...)
Syntax Example
keep packets.is_all_iterations(.kind,.protocol);

Parameters
struct-list

A list of struct.
Note The list cannot be multidimensional. Only one-dimensional lists are
allowed.

field-name

A scalar field of a struct: The field name must be prefixed by a period.


Note

The field cannot be a list type.

Specman e Language Reference


1999-2015

635
.

Product Version 15.1


All Rights Reserved.

Description
Causes a list of structs to have all legal, non-contradicting iterations of the fields specified in the field
list. The fields are iterated from right to left. Fields not included in the field list are not iterated; their
values can be constrained by other relevant constraints.

Usage Rules for is_all_iterations()


There are a number of usage rules for creating iterated lists that you must follow. These rules are
described in Iterating All Combinations of Legal Values for Given Fields in a List in the Specman
Generation User Guide. Refer to this section before writing is_all_iterations() constraints to ensure
accurate code.

Memory Usage and Performance Considerations


The number of iterations in a list produced by list.is_all_iterations() is the product of the number of
possible values in each field in the list. For example, if you list all iterations of a struct with the
following fields:
i: int [0..4]
j: int [0..3, 5..7]
k: int (bits: 8)

// 5 possible values
// 7 possible values
// 256 possible values

The number of iterations for the list is:


5 * 7 * 256 = 8960

Using is_all_iterations() can thus easily generate large lists. The generator issues the warning
GEN_AI_BIG_SOLUTION_SPACE when the generated list exceeds 10,000 values. Such a large list
can cause performance and memory overhead.
The absolute_max_list_size generation configuration option sets the maximum list size. The default is
524,288. If the number of iterations in your list exceeds this number, you can set
absolute_max_list_size to a larger number with the config gen command.

See Also

keep on page 620

constraint-def on page 618

Specman e Language Reference


1999-2015

636

Product Version 15.1


All Rights Reserved.

11.1.7

soft... select

Purpose
Constrain distribution of values

Category
Constraint definition

Syntax
soft gen-item==select {weight: value; ...}
soft input-bool-exp => gen-item==select {weight: value; ...}
Syntax Example
keep soft me.opcode == select {
30: ADD;
20: ADDI;
10: [SUB, SUBI];
};

Parameters
Like

gen-item

A generatable path.

input-bool-exp

A Boolean expression that is an input to the constraint, meaning that it can be


sampled only (it cannot be generatable).

weight

An int expression within the range 0 to MAX_INT.


Weights are proportions; they do not have to add up to 100. A relatively higher
weight indicates a greater probability that the value is chosen.
The probability for a given weight is calculated as:
weight / (sum of all weights)

Specman e Language Reference


1999-2015

637
.

Product Version 15.1


All Rights Reserved.

value

Sets the value or set of values that are valid samples for the given weight.
You can set the value parameter in two basic ways:

With an e expression (see Setting the value Parameter with an e Expression


on page 638).

Using keywords that are specific to soft...select constraints (see Setting the
value Parameter with a soft...select Keyword Policy on page 640).

Notes

The value can be either the same type as the gen-item or (for scalars) a set of
the same type items as the gen-item.
Each weight:value combination can be set in a different way.

Description
Specifies the relative probability that a particular value or set of values is chosen from the current range
of legal values for the gen-item. The current range is the range of values as reduced by the current set of
constraints on the gen-item.
Notes

Any given weight:value combination is canceled if it evaluates to value(s) that are not in the current
range of legal values for the gen-item.
If no weight:value combination succeeds in generating values in the range of the gen-item, the
soft..select constraint is ignored and a warning message is displayed.
Like other soft constraints, soft...select constraints are not met if they conflict with hard constraints.

Setting the value Parameter with an e Expression


You can use any e expression to set the value parameter, including expressions that contain user-defined
methods and variables:

If the gen-item is not a scalar type, the type of the value expression must be the same as the gen-item
type.
You can use the predefined routines for randomizing scalar/real numbers using uniform or normal
distribution. See Routines for Random Distribution of Numbers on page 1481 for more information.

Note As described in Differences in the Evaluation of e Expressions Versus Keyword Policies on


page 640, the e expression is evaluated once, when solving starts. This means that any generative fields
in the e expression are inputs into the soft...select constraint. To avoid problems caused by such inputs,
run the gen lint -i command to identify any resulting ICFSs before running simulation.

Specman e Language Reference


1999-2015

638

Product Version 15.1


All Rights Reserved.

Following are examples of e expressions used to set the value parameter. (More examples appear under
Using Random Distribution Routines to Generate Values on page 643 and Weighting the Values of List
Elements on page 643.)

Selecting string values:


a : string;
keep soft a == select {10: "abc"; 10:"cba";};

Selecting values that are either 0 or the values of a range of variables generated earlier:
keep soft my_fld == select {10: [bottom..top]; 20: 0;};

Using set functions to select a value between two int variables generated earlier (a and b) but not 10
or 15 if possible.
keep soft x == select {1: [a..b].diff([10,15]);};

Generating a list of packets where a packet will contain a flipped bits value of the previous packet if
possible:
struct packet {
x : int;
keep soft x == select {1: ~sys.prev_val;};
post_generate() is also {
sys.prev_val = x;
};
};
extend sys {
!prev_val : int;
};

Dealing with generative fields used in the e expression:


The soft...select constraint in the following code is ignored because the final hard constraint keep
result1 > top1 overrides the soft...select constraint. Thus, generation succeeds.
Because, however, generated fields (in this case, bottom1 and top1) in the e expression are
inputs to the soft...select constraint, the following code creates an ICFS:
keep top1 > bottom1;
keep top1 < 100;
keep soft result1==select {
1 : [bottom1..top1];
};
keep result1 > top1; // creates ICFS

To ensure that your code does not cause ICFSs, run the gen lint -i command before running any
tests. For more information, see Resolving Inconsistently Connected Field Sets (ICFSs) in the
Specman Generation User Guide

Specman e Language Reference


1999-2015

639
.

Product Version 15.1


All Rights Reserved.

Setting the value Parameter with a soft...select Keyword Policy


You can use the following select...soft keyword policies to define the value:

edgesSelects the values at the extreme ends of the current range(s).

minSelects the minimum value of the current range for gen-item.

maxSelects the maximum value of the current range forgen-item.

normal(mean, standard-deviation)Randomizes the values of the current range for gen-item as per
the given normal distribution, thus allowing a non-uniform distribution of values. The variables are
constant values:

mean (also called expectation) is the location of the peak.


standard-deviation identifies how much variation exists from the mean.
mean and standard-deviation can be integers or real (floating point) constant numbers.

othersSelects the portions of the current range that do not intersect with other non-zero select
expressions in this constraint.
When using others, an item with zero weight is not taken into account.

passIgnores this constraint and keeps the current range as is.

Note You cannot use edges, min, max, or normal when the gen-item is not a scalar type. (Using
others or pass is fine when the gen-item is not a scalar type.)
Following are examples of e expressions used to set the value parameter. (More examples appear under
Use of the Keyword pass on page 642 and Use of the Keywords others and edges on page 642.)

Using others when the gen-item is a string:


a : string;
keep soft a == select {10: "abc"; 10:"cba"; 10: others;};

Generating a random data packet with size between 1 and 40 bytes where it is know that most packets
are between 9 and 19 bytes.
struct packet {
length : int[1..40];
keep soft length = select {1: normal(14,6.0)};
};

Differences in the Evaluation of e Expressions Versus Keyword Policies


An e expression used to define value is evaluated only oncewhen solving startsand the evaluation is
not based on the current range of the gen-item. This means that the value of the expression does not
change if the gen-item current range changes because of other constraints.

Specman e Language Reference


1999-2015

640

Product Version 15.1


All Rights Reserved.

On the other hand, when a select...soft keyword policy is used, the value is derived from the gen-items
current range. Thus, for example, the value for the min policy in the following example is 6, not
MIN_INT:
x : int;
keep x > 5;
keep soft x == select {99: min; 1: pass;}

Similarly, the two soft...select constraints in the following example are not equivalent because the range
for x for the normal() distribution starts at 6, while the range for x for the dist_normal() distribution
starts at MIN_INT:
x : int;
keep x > 5;
keep soft x == select {1: normal(0,100);};
keep soft x == select {1: dist_normal(MIN_INT,MAX_INT,0,100);};

Example 1

Weighting Enumerated Values

The following soft select constraint specifies that there is a 3/6 probability that ADD is selected from the
current range, a 2/6 probability for ADDI, and a 1/6 probability that either SUB or SUBI is selected.
<'
type cpu_opcode: [
ADD, ADDI, SUB, SUBI,
AND, ANDI, XOR, XORI,
JMP, JMPC, CALL, RET,
NOP
] (bits: 4);
struct instr {
%opcode: cpu_opcode;
keep soft me.opcode == select {
30: ADD;
20: ADDI;
10: [SUB, SUBI];
};
};
'>

Example 2

Weighting Scalar Ranges

In the following example, address is generated in the range [0..49] 10% of the time, as exactly [50]
60% of the time, and in range [51..99] 30% of the time, assuming that the current range includes all these
values.
Specman e Language Reference
1999-2015

641
.

Product Version 15.1


All Rights Reserved.

struct transaction {
address: uint;
keep soft address == select {
10: [0..49];
60: 50;
30: [51..99];
};
};

Example 3

Use of the Keyword pass

This particular test uses the distribution described in the original definition of transaction only 10% of
the time and uses the range [200..299] 90% of the time. (See Example 2 on page 641 for the original
definition of transaction.)
<'
struct transaction {
address : uint;
keep soft address == select {
10 : [0..49];
60 : 50;
30 : [51..99];
};
};
extend transaction {
keep soft address == select {
10: pass;
90: [200..299];
};
};
'>

The final distribution is 90% [200..299], 1% [0..49], 6% [50], 3% [51..99].

Example 4

Use of the Keywords others and edges

This extension to transaction sets the current range with a hard constraint. 50% of the time the extreme
edges of the range are selected (0, 50, 100, and 150). 50% of the time other values in the range are
chosen.
<'
struct transaction {
address : uint;
keep soft address == select {
10 : [0..49];
Specman e Language Reference
1999-2015

642

Product Version 15.1


All Rights Reserved.

60 : 50;
30 : [51..99];
};
};
extend transaction {
keep address in [0..50,100..150];
keep soft address == select {
50: edges;
50: others;
};
};
'>

Example 5

Using Random Distribution Routines to Generate Values

The example below uses predefined distribution routines to generate packets with more weight to the
edges of the original domain:
struct packet {
var x : int;
keep (my_min() <= x) and (x <= my_max());
\\ The following constraint:
\\ 1) generates normally around the min
\\ 2) generates normally around the max
\\ 3) generates uniformly over all the domain
\\ 4) again generates uniformly over all the domain(using a range)
keep soft x==select {
40: dist_normal(my_min(),my_max(),my_min(),20);
40: dist_normal(my_min(),my_max(),my_max(),20);
10: dist_uniform(my_min(),my_max());
10: [my_min()..my_max()] ;
}
my_min() : int { result = 10 };
my_max() : int { result = 200 };
};

Example 6

Weighting the Values of List Elements

This example shows how to weight the values of generated elements of a list. The it variable is used to
represent a list element in the keep for each construct. The values A, B, and C are given equal weights
of 20, and all other possible values (D through L) are given a collective weight of 40. About 20% of the
generated list elements will be A, 20% will be B, 20% will be C, and the remaining 40% will get random
values in the range D through L.

Specman e Language Reference


1999-2015

643
.

Product Version 15.1


All Rights Reserved.

<'
type alpha: [A, B, C, D, E, F, G, H, I, J, K, L];
struct top {
my_list[50]: list of alpha;
keep for each in my_list {
soft it == select {
20: A;
20: B;
20: C;
40: others;
};
};
};
extend sys {
top;
};
'>

See Also

keep on page 620

constraint-def on page 618

Defining Soft and Soft Select Constraints on a Single Generatable Variable in the Specman

Generation User Guide

11.1.8

gen-item.reset_soft()

Purpose
Quit evaluation of soft constraints for a field

Category
Constraint definition

Syntax
gen-item.reset_soft()
input-bool-exp => gen-item.reset_soft()
Specman e Language Reference
1999-2015

644

Product Version 15.1


All Rights Reserved.

Syntax Example
keep c.reset_soft();

Parameters
gen-item

A generatable path.

input-bool-exp

A Boolean expression that is an input to the constraint, meaning that it can be


sampled only (it cannot be generatable).

Description
Causes the generator to quit the evaluation of soft value constraints for the specified field (generatable
item). The generator continues to evaluate soft constraints for other fields.
You can use reset_soft() to over-load or discard a default soft behavior of your model.

Example 1
It is important to remember that soft constraints are considered in reverse order to the order in which
they are defined in the e code. In the following example, the generator:
1.

Applies the keep soft c > 5 and c < 10 constraint (the last one defined).

2.

Quits the evaluation of soft value constraints for c when it encounters the keep c.reset_soft()
constraint.

In other words, it never considers the keep soft c < 3 constraint. It does evaluate the keep soft d< 3
constraint:
struct adder {
c: uint;
d: uint;
keep soft c < 3;

// Is not considered because of the


// reset_soft() below.

keep soft d < 3;


};
extend adder {
keep c.reset_soft(); // Stops evaluation of soft constraints on c.
};
extend adder {
keep soft c > 5 and c < 10;
};

Specman e Language Reference


1999-2015

645
.

Product Version 15.1


All Rights Reserved.

Example 2
This example shows the use of reset_soft() in the situation where a soft constraint is written with the
intent that it will be ignored if other constraints are added in an extension. Normally, address should
be less than 64. The test writer needs to do nothing additional to get this behavior.
In a few tests, address should be any value less than 128. The test writer needs to remove the effect of
the soft constraint so that it does not reduce the range [0..128] to [0..64].
struct transaction {
address: uint;
keep soft address < 64;
};
extend transaction {
keep address.reset_soft();
keep address < 128;
};

See Also

keep on page 620

constraint-def on page 618

11.1.9

name is [only]

Purpose
Define a named constraint

Category
Constraint

Syntax
keep name is [only]]
Syntax Example
keep address_range is soft addr in [0..9];
keep data_size is TRUE;
keep data_pattern is for each in data {
it != 0 and it != 7;
};
Specman e Language Reference
1999-2015

646

Product Version 15.1


All Rights Reserved.

keep data_size is only all of {


data.size() > 10;
data.size() < 20;
};
keep data_pattern is only TRUE;

Parameters
name

Any legal identifier used to identify the constraint for reference in


extensions and in different tools of the verification environment.

is only

The current definition of the constraint overrides any previous definition.

Description
All constraints can be named, including:

Boolean constraint definitions

Compound Constraint Block constraint blocks

for each constraints

type ...is aconstraints

struct-list.is_all_iterations() constraints

soft... select constraints

gen-item.reset_soft() constraints

Note Because named constraints are considered struct members, a name cannot be attached to
constraint definitions inside a gen keeping action or inside compound constraint expressions, such as
keep for each or a compound constraint block. However, an entire for each or compound constraint
block can be named.

Usage of Named Constraints


The main uses of named constraints are to:

Clarify the content and function of a constraint.

Define a basic constraint function, to be implemented differently in different subtypes.

Make it possible to reset or rewrite problematic constraint in a patch

Group several constraints that are relevant to the same issue under a specific name, especially when
using a compound constraint block.

Specman e Language Reference


1999-2015

647
.

Product Version 15.1


All Rights Reserved.

Every named constraint must have exactly one actual definition per struct type. An initial definition of a
constraint in a struct type may be overridden in like and when subtypes or in later extensions of the same
struct any number of times using the is only modifier.
The semantics of constraint overriding is identical to overriding of other extendable struct members,
such as methods. A constraint can be rewritten in different when subtypes (even if they are not
contradictory), and the latest entity that is valid to the generated subtype is chosen. It follows that the
variables of a constraint depend on every when determinant under which this constraint is rewritten.
Relations contrary to this (either unidirectional or bidirectional) lead to an ICFS and are reported in the
gen lint -i report.
Note If a named constraint is also a type constraint, if must not be overridden with another constraint
using is only.

Example
This example illustrates the rules for constraint overriding.
<'
struct packet {
size: [big, small];
addr: uint (bits: 16);
keep address_range is addr in [5..13];--#1.1
data: list of byte;
keep data_size is TRUE;--#2.1
};
struct regular_packet like packet {
when big regular_packet {
keep data_size is only data.size() > 8;--#2.2
keep address_range is only addr < 10;--#1.2
};
};
extend regular_packet {
corrupt: bool;
when corrupt regular_packet {
keep data_size is only data.size() == 0;--#2.3
};
};
struct special_packet like packet {
keep data_size is only data.size() < 50;--#2.4
keep address_range is only TRUE; --#1.3
};
'>
Specman e Language Reference
1999-2015

648

Product Version 15.1


All Rights Reserved.

Table 11-1

Example of Over-riding Named Constraints

Packet Subtypes

Constraints Enforced

big FALSE'corrupted regular_packet

Constraints #1.2 and #2.2 are enforced.

big TRUE'corrupted regular_packet

Constraints #1.2 and #2.3 are enforced.

small TRUE'corrupted regular_packet

Constraints #1.1 and #2.3 are enforced.

special_packet

Constraints #2.4 is enforced (constraint #1.3 is


used to reset #1.1)

11.1.10 read_only()
Purpose
Modify generation sequence.

Category
Pseudo-method

Syntax
read_only(espression: exp)
value(espression: exp)
Note For the Specman generator, read_only() and value() are equivalent. If you are using Pgen,
however, these two pseudo-methods differ. For information about the Pgen version of value(), see value()
in the Specman Pgen User Guide
Syntax Example
keep i < read_only(j);

Parameters
espression

A legal e expression.

Specman e Language Reference


1999-2015

649
.

Product Version 15.1


All Rights Reserved.

Description
Computes the value of the expression and makes this expression an input to the constraint (that is, the
constraint is unidirectional).
If the expression contains generative elements, these elements are generated before the connected field
set (CFS) to which the constraint belongs.

Example
keep a == read_only(b + c)

Note the following:

b and c are generated before a.


Because the constraint is unidirectional, also constraining a and b or a and c in bidirectional constraints
is not allowed. Doing so would create an inconsistently connected field set (ICFS).

See Also

Overview of Inconsistently Connected Field Sets (ICFSs) in the Specman Generation User Guide

Working with Input Dependencies in Constraints in the Specman Generation User Guide

11.1.11 Unidirectional Constraint Operators


Table 11-2 describes the unidirectional constraint operators.

In addition, the following sections are useful for understanding how unidirectional constraints can affect
generation:

Overview of Inconsistently Connected Field Sets (ICFSs) in Specman Generation User Guide

Working with Input Dependencies in Constraints in Specman Generation User Guide

Expressions that Are Implicitly Defined as Inputs by the Generator in Specman Generation User Guide
describes how to identify expressions that you may think are generative but that the generator
implicitly transforms to inputs.

Table 11-2

Unidirectional Operators for Generation

Operator

Example

Determinant/
Dependent

list in list

keep list1 in list2

list2/list1

list slicing

keep list1[7..9] == list2

list1/list2

Specman e Language Reference


1999-2015

650

Product Version 15.1


All Rights Reserved.

Table 11-2

Unidirectional Operators for Generation

Operator

Example

Determinant/
Dependent

all user-defined methods

keep my_method(x) == y

x/y

Most predefined methods,


such as:

keep list1.is_a_permutation(list2);

list2/list1

keep x == list1.max(it);

it/x

keep x == ipow(y,3);

y/x

get_enclosing_unit()
read_only()

Most predefined list


pseudo-methods, such as:

list.is_all_iterations()
list.is_a_permutation()

Note The following


predefined methods and list
pseudo-methods are
bidirectional:

abs()
max()
min()
list.and_all()
list.all_different()
list.count()
list.has()
list.max_value()
list.min_value()
list.or_all()
list.sum()

See also Using Bidirectional


Generative List
Pseudo-Methods in
Specman Generation User
Guide.
soft...select

keep soft opcode == select {


weight: ADD;
50: SUB;
};

Specman e Language Reference


1999-2015

651
.

weight/opcode

Product Version 15.1


All Rights Reserved.

Table 11-2

Unidirectional Operators for Generation


Determinant/
Dependent

Operator

Example

reset_soft() or soft...select
in compound constraint

keep soft mode => opcode == select {


30: ADD;
20: ADDI;
10:[SUB, SUBI];
};
keep (op2 > 2K) =>
opcode.reset_soft();
};

mode/opcode

as_a on like subtypes


(except in type constraints)

keep my_engine ==
my_car.as_a(ford_car).ford_engine

my_car/
my_engine

is a on like subtypes
(except in type constraints)

keep my_car is a ford_car =>


my_engine.kind == FORD

my_car/
my_engine

Named is a on when
subtypes (except when it
appears as the left side of
an unconditional and
constraint)

keep my_engine is a FORD engine (fe)


=> fe.size == 1600
keep (my_car is a ford_car) =>
(my_engine is a FORD engine (fe)
and fe.size == 1600)

my_engine.kind/my
_engine.FORD'size

op2/opcode

But not:
keep my_engine is a FORD engine (fe)
and fe.size == 1600
(here they are both generatives)

11.2 Initiating Generation On the Fly


You can constrain and generate values for particular struct instances, fields, or variables during
simulation (on-the-fly generation) with the gen action.

gen...keeping on page 653

See Also

! described in field on page 225

Sequence Item do Actions on page 933

Specman e Language Reference


1999-2015

652

Product Version 15.1


All Rights Reserved.

11.2.1

gen...keeping

Purpose
Generate values for an item

Category
Action

Syntax
gen gen-item [keeping {[it].constraint-def; ...}]
Syntax Example
gen next_packet keeping {
.kind in [normal, control];
};

Parameters
gen-item

A path starting with me, a local variable, or sys.

constraint-def

A constraint definition. For more information, see constraint-def on page 618.

Description
Generates a random value for the instance of the item specified in the expression and stores the value in
that instance, while considering all the constraints specified in the keeping block as well as other
relevant constraints at the current scope on that item or its children.
Constraints defined at a higher scope than the enclosing struct (constraints from above) apply only to
fields that are marked as do-not-generate. For more information about constraints from above, see
Defining Constraints from Above (CFAs) in the Specman Generation User Guide.
You can generate values for particular struct instances, fields, or variables during simulation (on-the-fly
generation) with the gen action.

Notes

You can use the soft keyword in the list of constraints within a gen action.

The gen action cannot be used from the Specman> prompt.

Specman e Language Reference


1999-2015

653
.

Product Version 15.1


All Rights Reserved.

A gen action can be called only after the test setup phase is finished.
A gen action can be called from any method of user structs, including init(), pre_generate(), and
post_generate().
A gen action cannot be called from global methods or to generate global fields.
The generatable item for the gen action cannot include an index reference or a list size. For example,
gen sys.pckts[index].dat; gen sys.pckts.dat[index];, and gen sys.pckts.size() are all illegal.

Example 1
This example uses the gen action within a TCM called gen_next() to create packets to send to the
device under test. A constraint within the gen action keeps len with a range of values. A constraint
defined at a lower scope level, packet, is also applied when the gen action is executed, keeping the
size of the data field equal to the len field. The constraint defined at the sys level keep
sp.next_packet.len == 4; is not considered because it is not at the current scope of the gen action.
extend sys {
event event_clk is @sys.any;
sp: send_packet;
keep sp.next_packet.len == 4;
};
struct packet {
len: int [0..10];
kind: [normal, control, ack];
data: list of int;
keep me.data.size() == len;
};
struct send_packet {
!num_of_packets_to_send: int [0..20];
!next_packet: packet;
gen_next() @sys.event_clk is {
gen num_of_packets_to_send; // Random loop delimiter
for i from 0 to num_of_packets_to_send - 1 do {
wait ([100]*cycle);
gen next_packet keeping {
.len in [5..10];
.kind in [normal, control];
};
};
};
run() is also {
start gen_next();
};

Specman e Language Reference


1999-2015

654

Product Version 15.1


All Rights Reserved.

};

Example 2
This example shows a keep soft ... select constraint on the gen action, which weights the distribution of
values for the len field of a packet.
struct packet {
len: int [0..10];
kind: [normal, control, ack];
};
struct top {
!packet_list: list of packet;
pkt_gen() is {
var pkt: packet;
for i from 0 to 100 {
gen pkt keeping {
soft it.len == select {
20: [0..3];
60: [4..6];
20: [7..10];
};
};
packet_list.add(pkt);
};
};
};

Example 3
This example shows how to generate a struct containing a list on the fly, while constraining each item in
the list.
Note You must provide a name for the list item that is iterated. In other words substituting for each
in .data for for each (item) in .data causes an error.
struct packet {
addr: uint;
data: list of byte;
};
extend sys {
send_packet()@sys.any is {
var p: packet;
Specman e Language Reference
1999-2015

655
.

Product Version 15.1


All Rights Reserved.

gen p keeping {
it.addr > 450000;
for each (d) in .data {
d > 10 and d < 30;
};
};

// name is required

};
};

See Also

Defining Constraints on page 617

Using Procedural Code During Generation on page 656

11.3 Using Procedural Code During Generation


You can extend the predefined method pre_generate() of any struct to prepare for generation by
assigning values to the structs non-generatable fields. Similarly, you can extend the predefined method
post_generate() of any struct to complete generation by assigning values to the structs non-generatable
fields.

pre_generate() on page 656

post_generate() on page 658

See Also

Calling Procedural Code During Generation in Specman Generation User Guide

Using Methods in Constraints in Specman Generation User Guide

generate in the Specman Command Reference

11.3.1

pre_generate()

Purpose
Method run before generation of struct

Category
Method of any struct
Specman e Language Reference
1999-2015

656

Product Version 15.1


All Rights Reserved.

Syntax
[struct-exp.]pre_generate() is also ...
Syntax Example
pre_generate() is also {
m = 7;
};

Parameters
struct-exp

An expression that returns a struct. The default is the current struct.

Description
The pre_generate() method is run automatically after an instance of the enclosing struct is allocated but
before generation is performed. This method is initially empty, but you can extend it to apply values
procedurally to the structs non-generatable fields. This is useful if you want other values in the struct to
reflect the values of the structs non-generatable fields.
The order of generation is recursively as follows:
1.

Allocate the new struct.

2.

Call pre_generate().

3.

Perform generation

4.

Call post_generate().

Note Prefix the ! character to the name of any field whose value is determined by pre_generate().
Otherwise, normal generation will overwrite this value.

Example
struct a {
!m: int;
m1: int;
keep m1 == m + 1;
pre_generate() is also {
m = 7;
};
};
extend sys {
A: a;
};
Specman e Language Reference
1999-2015

657
.

Product Version 15.1


All Rights Reserved.

See Also

Defining Constraints on page 617

Defining Constraints on page 617

Initiating Generation On the Fly on page 652

11.3.2

post_generate()

Purpose
Assign values based on other values produced during generation

Category
Predefined method of any struct

Syntax
[struct-exp.]post_generate() is also ...
Syntax Example
post_generate() is also {
m = m1 + 1;
};

Parameters
struct-exp

An expression that returns a struct. The default is the current struct.

Description
The post_generate() method is run automatically after an instance of the enclosing struct is allocated
and both pre-generation and generation have been performed. You can extend the predefined
post_generate() method for any struct to derive more complex expressions or values from the generated
values and apply them to the structs non-generatable fields.
The order of generation is recursively as follows:
1.

Allocate the new struct.

2.

Call pre_generate().

Specman e Language Reference


1999-2015

658

Product Version 15.1


All Rights Reserved.

3.

Perform generation.

4.

Call post_generate().

Example
struct a {
!m: int;
m1: int;
post_generate() is also {
m = m1 + 1;
};
};
extend sys {
A: a;
};

See Also

Defining Constraints on page 617

Initiating Generation On the Fly on page 652

11.4 Macro for Choosing the Generator


11.4.1

IF_USING_GEN(name)

Purpose
Identify generator-specific code

Category
Macro

Syntax
IF_USING_GEN(generator-name)
Syntax Example
<'
extend sys {
x:uint;
Specman e Language Reference
1999-2015

659
.

Product Version 15.1


All Rights Reserved.

l: list of uint;
IF_USING_GEN(IntelliGen) {
keep for each in l {
it == value(x);
};
};
IF_USING_GEN(Pgen) {
keep gen (x) before (l);
keep for each in l {
it == x;
};
};
};
'>

Parameters
generator-name

Either IntelliGen or Pgen.

Description
This macro makes the enclosed code visible only if the specified generator name matches the current
setting of the config gen -default_generator option. This macro is useful if you plan to use the code
with both Pgen and IntelliGen.

Specman e Language Reference


1999-2015

660

Product Version 15.1


All Rights Reserved.

12

Events

The e language provides temporal constructs for specifying and verifying behavior over time. All e
temporal language features depend on the occurrence of events, which are used to synchronize activity
with a simulator and within Specman.
This chapter contains the following sections:

event on page 662

emit on page 666

See Also

Defining and Working With Events in Creating e Testbenches

Defining Structs on page 216

Rules for Extending Methods in Creating e Testbenches

Invoking Methods on page 535

Chapter 13 Temporal Expressions

Chapter 14 Temporal Struct and Unit Members

Chapter 15 Time-Consuming Actions

Specman e Language Reference


1999-2015

661
.

Product Version 15.1


All Rights Reserved.

12.1 event
Purpose
Define a named event

Category
Struct member

Syntax
event event-type [is temporal-expression [using temporal-operators]]
event event-type [is only temporal-expression] [using also temporal-operators]
Syntax Example
event clk is rise('top.cpu_clk') @sim;

Parameters
event-type

The name you give the event type. It can be any legal e identifier.

temporal-expression An event or combination of events and temporal operators.


To use an event name alone as a temporal expression, you must prefix the event
name with the @ sign. For example, to define event A to succeed whenever event
D succeeds, you must use the @ in front of D: event A is @D. For more
information about temporal expressions, see Chapter 13 Temporal Expressions.

Specman e Language Reference


1999-2015

662

Product Version 15.1


All Rights Reserved.

temporal--operators You can specify up to three temporal operators. Each operator consists of two
parts: an operation and a condition. Upon detection of the condition, the operation
is performed.
The following are possible operations:
abort

Terminate evaluation of the temporal expression in the current


tick, and restart it in the next tick.

[exclusive_]start start and exclusive_start both start the evaluation of the


temporal expression in the current tick if the event is currently
in a stopped state.
Furthermore, exclusive_start also means that the event is
stopped when the struct is created, and remains stopped until
acted upon by the exclusive start.
stop

Stop the evaluation of the temporal expression in the current


tick. It will remain stopped until a start instruction is issued.

The following are possible conditions:


@event-name

Triggering temporal event. This event can be in the same struct


(that is, [me.]event-name), or reachable via a constant path (that
is, const-or-unit-instance-field-path.event-path).

none

Return to the default state. This value is intended for use when
there was a previous triggering event for this instruction that
should be removed.

empty

Used to specify a dummy event (i.e., an event that never


happens), for use with the procedural API. (For more
information, see Scheduler Methods on page 1260.)

Description
Events can be attached to temporal expressions, using the option is [only] temporal-expression syntax,
or they can be unattached. An attached event is emitted automatically during any Specman tick in which
the temporal expression attached to it succeeds.
Events, like methods, can be redefined in struct extensions. The is only temporal-expression syntax in a
struct extension is used to change the definition of an event. You can define an event once, and then
attach it to several different temporal expressions under different when struct subtypes, using the is only
syntax.

Specman e Language Reference


1999-2015

663
.

Product Version 15.1


All Rights Reserved.

Temporal operators can be attributed to an event which has a temporal expression, with using syntax in
a definition, or using also in a redefinition of the event, or added as a separate extension to an existing
event with using also.

Example 1
In the following, start_ct is an unattached event, and top_clk and stop_ct are attached events. The
m_str extension contains a redefinition of the stop_ct event.
struct m_str {
event start_ct;
event top_clk is fall('top.r_clk') @sim;
event stop_ct is {@start_ct; [1]} @top_clk;
};
extend m_str {
event stop_ct is only {@start_ct; [3]}@top_clk;
};

Example 2
One way to cause a Specman callback from the simulator is to sample a change, rise, or fall of a
simulator object using @sim. The following causes a callback and a sim_ready event whenever the
value of the simulator object top/ready changes.
event sim_ready is change('top/ready') @sim;

Example 3
The emit action can be used to force any event to occur. The emit action in the following forces the
sim_ready event to occur even if the change('top/ready') @sim temporal expression has not
succeeded.
struct sys_ready {
event sim_ready is change('top/ready') @sim;
bar() @sys.clk is {
while TRUE {
wait until @sys.ok;
wait [1] *cycle;
emit sim_ready;
};
};
};

Specman e Language Reference


1999-2015

664

Product Version 15.1


All Rights Reserved.

Example 4
The following example illustrates how to create an e event on a bit slice. As shown in the e code, you do
this by creating an e port that is bound to the bit slice and then create the event based on a change in
value for this port.
SystemVerilog Code:
module top;
reg [31:0] r;
initial begin
#5 r[0] = 1;
#10;
$finish;
end
endmodule

e Code:
unit ver {
r: in simple_port of uint is instance;
keep bind(r,external);
keep r.hdl_path() == "~/top/r";
r_0: in simple_port of uint is instance;
keep bind(r_0,external);
keep r_0.hdl_path() == "~/top/r[0:0]";
event my_ev is change(r_0$)@sim;
body() @my_ev is {
out("Event for r[0]: ",r$," At time ",sys.time);
};
run() is also {
start body();
};
};
extend sys {
ver is instance;
keep ver.agent() == "Verilog";
};

Note Creating an event on the bit slice itself is not supported. For example, the following e code is
not supported:
r: in simple_port of uint is instance;
keep bind(r,external);
keep r.hdl_path() == "~/top/r";
Specman e Language Reference
1999-2015

665
.

Product Version 15.1


All Rights Reserved.

event my_ev is change(r$[0:0])@sim; // not supported

See Also

Chapter 13 Temporal Expressions

method @event is on page 521

show events in the Specman Command Reference

trace events in the Specman Command Reference

emit on page 666

12.2 emit
Purpose
Cause a named event to occur

Category
Action

Syntax
emit [struct-exp.]event-type
Syntax Example
emit ready;

Parameters
struct-exp

An expression referring to the struct instance in which the event is defined.

event-type

The type of event to emit.

Description
Causes an event of the specified type to occur immediately.
At the end of each tick, all temporal expressions that contain an event that was emitted during that tick
are evaluated. Then, functions that depend on that event are called, including the function that handles
on constructs and the function that handles cover constructs.
Specman e Language Reference
1999-2015

666

Product Version 15.1


All Rights Reserved.

The emit event does not consume time. It can be used in regular methods and in TCMs.
The simplest usage of emit is to synchronize two TCMs, where one TCM waits for the named event and
the other TCM emits it.

Example 1
<'
struct xmit_recv {
event rec_ev;
transmit() @sys.clk is {
wait cycle;
emit rec_ev;
out("rec_ev emitted");
};
receive() @sys.clk is {
wait until @rec_ev;
out("rec_ev occurred");
stop_run();
};
run() is also {
start transmit();
start receive();
};
};
extend sys {
event clk is @sys.any;
xmtrcv_i: xmit_recv;
};
'>

Example 2
In the following example, the event env_e is emitted eight times in a single tick, but cover_e occurs only
once at the end of the tick.
<'
struct cov_s {
event cover_e is @sys.env.env_e;
};
struct env_s {
cov : cov_s;
event env_e;
run() is also {
start m();
Specman e Language Reference
1999-2015

667
.

Product Version 15.1


All Rights Reserved.

};
m() @sys.any is {
start set_f();
wait [1];
stop_run();
};
set_f()@sys.any is {
for i from 0 to 8 do {
emit env_e;
};
};
};
extend sys {
env: env_s;
};
'>

See Also

event on page 662

Specman e Language Reference


1999-2015

668

Product Version 15.1


All Rights Reserved.

13

Temporal Expressions

Temporal expressions provide a declarative way to describe temporal behavior. The e language provides
a set of temporal operators and keywords that you can use to construct temporal expressions.

Temporal Operators and Constructs


This chapter describes the constructs you can use in temporal expressions:

not on page 670


fail on page 672
and on page 674
or on page 676
{ exp ; exp } on page 678
eventually on page 680
[ exp ] on page 681
[ exp..exp ] on page 683
~[ exp..exp ] on page 685
=> on page 687

detach on page 689


delay on page 691
@ unary event operator on page 693
@ sampling operator on page 694
cycle on page 696
true(exp) on page 697
change(exp), fall(exp), rise(exp) on page 699
consume on page 704
exec on page 707

In addition, it describes:

Precedence of Temporal Operators on page 670

See Also

Working with Temporal Expressions in Creating e Testbenches

Invoking Methods on page 535

Chapter 12 Events

Chapter 14 Temporal Struct and Unit Members

Chapter 15 Time-Consuming Actions

Specman e Language Reference


1999-2015

669
.

Product Version 15.1


All Rights Reserved.

13.1 Precedence of Temporal Operators


The precedence of temporal operators is shown in Table 13-1, listed from highest precedence to lowest.
Table 13-1

Precedence of Temporal Operators

Operator Name

Operator Example

@ unary event operator

@event-name

consume

consume (@event-name)

repeat

[ ] * TE

fail
not
eventually

fail TE
not TE
eventually TE

@ sampling operator

TE @ event-name

exec

TE exec action-block

and

TE1 and TE2

or

TE1 or TE2

sequence

{TE1 ; TE2}

yield

TE1 => TE2

See Also

Temporal Operators and Constructs on page 669

13.2 not
Purpose
Temporal expression inversion operator

Category
Temporal expression

Specman e Language Reference


1999-2015

670

Product Version 15.1


All Rights Reserved.

Syntax
not temporal-expression
Syntax Example
not {@ev_b;@ev_c}

Parameters
temporal-expression

A temporal expression.

Description
The not temporal expression succeeds if the evaluation of the subexpression does not succeed during the
sampling period. Thus not TE succeeds on every occurrence of the sampling event if TE does not
succeed.

Note
If an event is explicitly emitted (using emit on page 666), a race condition can arise between the event
occurrence and the not of the event when used in some temporal expression.

Example 1
In the following, the event ev_d occurs every time there is an occurrence of ev_c that is not preceded by
an occurrence of ev_a and then two consecutive occurrences of ev_b.
event ev_d is {not{ @ev_a; @ev_b; @ev_b}}; @ev_c} @clk;

See { exp ; exp } on page 678 for information about the ; sequence operator.

Example 2
The fail operator (see fail on page 672) differs from the not operator. Figure 13-1 on page 673 illustrates
the differences in behavior of not and fail for the sequence of ev_a, ev_b, and ev_c events shown at the
top of the figure. (See { exp ; exp } on page 678 for information about the ; sequence operator.)

See Also

Simulation Time and Specman Ticks in Creating e Testbenches

fail on page 672

Temporal Operators and Constructs on page 669

Specman e Language Reference


1999-2015

671
.

Product Version 15.1


All Rights Reserved.

13.3 fail
Purpose
Temporal expression failure operator

Category
Temporal expression

Syntax
fail temporal-expression
Syntax Example
fail{@ev_b; @ev_c}

Parameters
temporal-expression

A temporal expression.

Description
A fail succeeds whenever the temporal expression fails. If the temporal expression has multiple
interpretations (for example, fail (TE1 or TE2)), the expression succeeds if and only if all the
interpretations fail.
The expression fail TE succeeds at the point where all possibilities to satisfy TE have been exhausted.
Any TE can fail at most once per sampling event.

Note
The not operator differs from the fail operator.

Example
The expression
fail {@ev_b;@ev_c}

succeeds for any of the following conditions:


Specman e Language Reference
1999-2015

672

Product Version 15.1


All Rights Reserved.

event ev_b does not occur in the first cycle

ev_b succeeds in the first cycle, but event ev_c does not occur in the second cycle

Figure 13-1 on page 673 illustrates the differences in behavior of not and fail.

Figure 13-1

Comparison of Temporal not and fail Operators


@pclk
@ev_a
@ev_b
@ev_c
{@ev_b;@ev_c} @pclk
not{@ev_b;@ev_c} @pclk
fail{@ev_b;@ev_c} @pclk

{@ev_a; not{@ev_b;@ev_c}} @pclk


{@ev_a; fail{@ev_b;@ev_c}} @pclk

event emitted

evaluation starts

evaluation succeeds

evaluation fails

See Also

not on page 670

Temporal Operators and Constructs on page 669

Specman e Language Reference


1999-2015

673
.

Product Version 15.1


All Rights Reserved.

13.4 and
Purpose
Temporal expression and operator

Category
Temporal expression

Syntax
temporal-expression and temporal-expression
Syntax Example
(@TE1 and @TE2)@clk

Parameters
temporal-expression

A temporal expression.

Description
The temporal and succeeds when both temporal expressions start evaluating in the same sampling
period, and succeed in the same sampling period.

Example 1
Evaluation of the and temporal expression:
event TE3 is (TE1 and TE2) @qclk

for the following conditions:

Evaluation of both TE1 and TE2 begins on the first qclk. Both TE1 and TE2 succeed between the
second and third qclk so the event TE3 is emitted at the third qclk.
The evaluations of TE1 and TE2 that begin on the fourth qclk eventually result in success of both
TE1 and TE2, but TE1 succeeds before the fifth qclk, and TE2 succeeds before the sixth qclk.
Therefore, TE1 and TE2 does not succeed.
On the seventh qclk, evaluation of TE1 begins, and it succeeds before the eighth qclk. However, the
corresponding evaluation of TE2 fails during that period, so TE3 fails.

Specman e Language Reference


1999-2015

674

Product Version 15.1


All Rights Reserved.

is shown in Figure 13-2 on page 675.


Figure 13-2

Example 1 of Temporal and Operator Behavior


1

10

qclk
TE1
TE2
(TE1 and TE2)@qclk
TE3

event emitted

evaluation starts

evaluation succeeds

evaluation fails

Example 2
Evaluation of the and temporal expression:
event TE3 is (TE1 and TE2) @qclk

for the following conditions:

TE1 and TE2 both start evaluating at the first qclk.

TE1 and TE2 both succeed at the third qclk.


The and succeeds because both sides started evaluating at the same time and both succeeded at the
same time.

TE1 starts evaluating at the fourth qclk.

TE2 starts evaluating at the fifth qclk.

TE1 and TE2 both succeed at the sixth qclk.


The and does not succeed because the two sides started evaluating at different time.

is shown in Figure 13-3 on page 676,

Specman e Language Reference


1999-2015

675
.

Product Version 15.1


All Rights Reserved.

Figure 13-3

Example 2 of Temporal and Operator Behavior


1

10

qclk
TE1
TE2
(TE1 and TE2)@qclk
TE3

event emitted

evaluation starts

evaluation succeeds

evaluation fails

See Also

Creating Sampling Events in Creating e Testbenches

Temporal Operators and Constructs on page 669

13.5 or
Purpose
Temporal expression or operator

Category
Temporal expression

Syntax
temporal-expression or temporal-expression
Syntax Example
(@TE1 or @TE2)@clk
Specman e Language Reference
1999-2015

676

Product Version 15.1


All Rights Reserved.

Parameters
temporal-expression

A temporal expression.

Description
The or temporal expression succeeds when either temporal expression succeeds.
An or operator creates a parallel evaluation for each of its subexpressions. It can create multiple
successes for a single temporal expression evaluation.

Example
Evaluation of the temporal or operator:
event TE3 is (@TE1 or @TE2) @qclk;

for the following conditions:

Evaluation of both TE1 and TE2 begins on the first qclk, and succeed between the second and third
qclk, so TE1 or TE2 succeeds at the third qclk.
The evaluations of TE1 and TE2 that begin on the fourth qclk result in success of TE2 before the
fifth qclk, so TE3 succeeds at the fifth qclk.
Evaluation of TE1 or TE2 begins again at the seventh qclk, and TE1 succeeds before the ninth qclk,
so TE3 succeeds at the ninth qclk.

is shown in Figure 13-4 on page 678.

Specman e Language Reference


1999-2015

677
.

Product Version 15.1


All Rights Reserved.

Figure 13-4

Example of Temporal or Operator Behavior


1

10

qclk
TE1
TE2
(TE1 or TE2) @qclk
TE3

event emitted

evaluation starts

evaluation succeeds

evaluation fails

See Also

Creating Sampling Events in Creating e Testbenches

Temporal Operators and Constructs on page 669

13.6 { exp ; exp }


Purpose
Temporal expression sequence operator

Category
Temporal expression

Syntax
{temporal-expression; temporal-expression; ...}
Syntax Example
{@ev_d; @ev_e} @ev_f

Specman e Language Reference


1999-2015

678

Product Version 15.1


All Rights Reserved.

Parameters
temporal-expression

A temporal expression.

Description
The semicolon (;) sequence operator evaluates a series of temporal expressions over successive
occurrences of a specified sampling event. Each temporal expression following a ; starts evaluating in
the sampling period following that in which the preceding temporal expression succeeded. The sequence
succeeds whenever its final expression succeeds.

Note
Curly braces ({}) in the scope of a temporal expression define a sequence. They should not be used in
any other way.

Example
Figure 13-5 on page 679 shows the results of evaluating the temporal sequence:
{@ev_a; @ev_b; @ev_c} @qclk;

over the series of ev_a, ev_b, and ev_c events shown at the top of the figure. Evaluation of the sequence
starts whenever event ev_a occurs.
Figure 13-5

Example Evaluations of a Temporal Sequence


1

qclk
ev_a
ev_b
ev_c
{@ev_a;@ev_b;@ev_c}@qclk

event emitted

evaluation starts

evaluation succeeds

Specman e Language Reference


1999-2015

679
.

evaluation fails

Product Version 15.1


All Rights Reserved.

See Also

Creating Sampling Events in Creating e Testbenches

Temporal Operators and Constructs on page 669

13.7 eventually
Purpose
Temporal expression success check

Category
Temporal expression

Syntax
eventually temporal-expression
Syntax Example
{@ev_d; eventually @ev_e}

Parameters
temporal-expression

A temporal expression.

Description
Used to indicate that the temporal expression should succeed at some unspecified time.
Typically, eventually is used in an expect struct member to specify that a temporal expression is
expected to succeed sometime before the quit event occurs for the struct.

Example
The following instance of the temporal yield operator (see => on page 687) succeeds after the event ev_c
occurs only if event ev_a occurs in the next cycle, and then event ev_b occurs sometime before the
example struct instance is terminated. See { exp ; exp } on page 678 for information about the ;
sequence operator.

Specman e Language Reference


1999-2015

680

Product Version 15.1


All Rights Reserved.

struct example {
event ev_a;
event ev_b;
event ev_c;
expect @ev_c => {@ev_a; eventually @ev_b};
};

See Also

The quit() Method of any_struct or any_unit on page 1189

Temporal Operators and Constructs on page 669

13.8 [ exp ]
Purpose
Fixed repetition operator

Category
Temporal expression

Syntax
[exp] [* temporal-expression]
Syntax Example
wait [2]*cycle;

Parameters
exp

A 32-bit, non-negative integer expression, which specifies the number of


times to repeat the evaluation of the temporal expression. This cannot
contain functions.

Specman e Language Reference


1999-2015

681
.

Product Version 15.1


All Rights Reserved.

temporal-expression

A temporal expression.
If * temporal-expression is omitted, * cycle is automatically used in its
place. Thus the following two lines of code are equivalent:
wait [2]*cycle;
wait [2];

Description
Repetition of a temporal expression is frequently used to describe cyclic or periodic temporal behavior.
The [exp] fixed repeat operator specifies a fixed number of occurrences of the same temporal
expression.
If the numeric expression evaluates to zero, the temporal expression succeeds immediately.

Examples
The {...;...} syntax used in the examples below specifies a temporal sequence. The expressions are
evaluated one after another, in consecutive sampling periods. See { exp ; exp } on page 678 for
information about the ; sequence operator.
In the following example, the wait action proceeds after the sequence event ev_a, then three occurrences
of event ev_b, then event ev_c, all sampled at the default sampling event:
wait {@ev_a; [3]*@ev_b; @ev_c};

In the following example, the wait action proceeds after M+2 consecutive pclk cycles in which
sys.interrupt occurs. If there is a pclk cycle without a sys.interrupt, the count restarts from 0:
wait ([M+2] * @sys.interrupt)@pclk;

In the following example, the wait action proceeds on the occurrence of the ev_a event:
wait {@ev_a; [0]*@ev_b};

In the following example, the wait action proceeds five sampling event cycles after event ev_a:
wait {@ev_a; [5]};

The numeric expression cannot include any functions. The following two examples show how to
substitute temporary variables for functions in repeat expressions.
In a TCM, this is not legal:
wait [my_func()] * cycle; // illegal

To overcome this restriction, use a variable to hold the function value:


Specman e Language Reference
1999-2015

682

Product Version 15.1


All Rights Reserved.

var t: int = my_func();


wait [t] * cycle;

In expect, assume or event struct members, this is not legal:


event my_ev is { @ev_a; [my_func()] } @clk; // illegal

In this situation, use a field to hold the function value and an exec expression to execute the function:
!temp: int;
event my_ev is { @ev_a exec {temp=my_func()}; [temp] } @clk;

See Also

Temporal Operators and Constructs on page 669

13.9 [ exp..exp ]
Purpose
First match variable repeat operator

Category
Expression

Syntax
{ ... ; [[from-exp]..[to-exp] ] [* repeat-expression]; match-expression; ... }
Syntax Example
{[2..4]*@pclk;@reset}

Parameters
from-exp

An optional non-negative 32 bit numeric expression that specifies the


minimum number of repetitions of the repeat-expression. If the from-exp is
missing, zero is used.

to-exp

An optional non-negative 32 bit numeric expression that specifies the


maximum number of repetitions of the repeat-expression. If the to-exp is
missing, infinity is used.

Specman e Language Reference


1999-2015

683
.

Product Version 15.1


All Rights Reserved.

repeat-expression

The temporal expression that is to be repeated a certain number of times


within the from-exp..to-exp range. If the *repeat-expression is omitted,
*cycle is assumed.

match-expression

The temporal expression to match.

Description
The first match repeat operator is only valid in a temporal sequence {TE; TE; TE}. The first match
repeat expression succeeds on the first success of the match-expression between the lower and upper
bounds specified for the repeat-expression.
First match repeat also enables specification of behavior over infinite sequences by allowing an infinite
number of repetitions of the repeat-expression to occur before the match-expression succeeds.
Where @ev_a is an event occurrence, {[..]*TE1;@ev_a} is equivalent to:
{@ev_a} or {[1]*TE1; @ev_a} or {[2]*TE1; @ev_a} or {[3]*TE1; @ev_a}...

Examples
The following examples all make use of the {...;...} syntax for sequence temporal expressions since the
first match repeat operator is only allowed inside a sequence. See { exp ; exp } on page 678 for
information about the ; sequence operator.
In the following example, the wait action proceeds after the first occurrence of ev_a followed by ev_b at
pclk:
wait {[..]; {@ev_a; @ev_b}}@pclk

In the following example, the wait action proceeds after one or more occurrences of ev_a at consecutive
pclk events, followed by one occurrence of ev_b at the next pclk event:
wait {[1..]*@ev_a; @ev_b}@pclk

In the following example, the wait action proceeds after between zero and three occurrences of the
sequence {ev_a; ev_b} (sampled by pclk), followed by an occurrence of ev_c at the next pclk event:
wait {[..3]*{@ev_a; @ev_b}; @ev_c}@pclk

In the following example,


wait {@ev_a; [0..2]*@ev_b; @ev_c}@pclk

the wait action proceeds after any one of the three sequences sampled at consecutive sampling events:

{@ev_a; @ev_c}

Specman e Language Reference


1999-2015

684

Product Version 15.1


All Rights Reserved.

{@ev_a; @ev_b; @ev_c}


{@ev_a; @ev_b; @ev_b; @ev_c}

See Also

~[ exp..exp ] on page 685

cycle on page 696

[ exp ] on page 681

Temporal Operators and Constructs on page 669

13.10 ~[ exp..exp ]
Purpose
True match variable repeat operator

Category
Expression

Syntax
~[[from-exp]..[to-exp]] [* temporal-expression]
Syntax Example
~[2..4]*@pclk

Parameters
from-exp

An optional non-negative 32 bit numeric expression that specifies the


minimum number of repetitions of the temporal expression. If the
from-exp is missing, zero is used.

to-exp

An optional non-negative 32 bit numeric expression that specifies the


maximum number of repetitions of the temporal expression. If the to-exp is
missing, infinity is used.

Specman e Language Reference


1999-2015

685
.

Product Version 15.1


All Rights Reserved.

temporal-expression

The temporal expression that is to be repeated some number of times


within the from-expr..to-exp range. If *temporal-expression is omitted,
* cycle is assumed.

Description
You can use the true match repeat operator to specify a variable number of consecutive successes of a
temporal expression.
True match variable repeat succeeds every time the subexpression succeeds. This expression creates a
number of parallel repeat evaluations within the range.
True match repeat also enables specification of behavior over infinite sequences by repeating an infinite
number of occurrences of a temporal expression. The expression ~[..]*TE is equivalent to:
[0] or [1]*TE or [2]*TE...
This construct is mainly useful for maintaining information about past events. See [ exp ] on page 681.
The following are examples of both forms of variable repeats, using implicit and explicit from - to range
expressions:

Example 1
In the examples below, the {...;...} syntax specifies a temporal sequence. See { exp ; exp } on page 678
for information about the ; sequence operator.
The following temporal expression succeeds if A has occurred sometime during an earlier cycle:
{@A;~[..]}

The following temporal expression succeeds after any of the sequences {A}, {A; B}, {A; B; B}, or {A;
B; B; B}:
{@A;~[..3]*@B}

Example 2
The following temporal expression succeeds three pclk cycles after reset occurs, again at four pclk
cycles after reset, and again five pclk cycles after reset (with reset also sampled at pclk):
{@reset; ~[3..5]} @pclk

Specman e Language Reference


1999-2015

686

Product Version 15.1


All Rights Reserved.

Example 3
The following temporal expression using the and temporal operator succeeds if A is followed at any
time by B, or if A and B both occur during the same initial cycle:
{@A; ~[..]} and {[..]; @B}

Note

A more efficient way to write the above example is:

(@A and @B) or {@A; [..]; @B}

See Also

[ exp..exp ] on page 683

cycle on page 696

[ exp ] on page 681

Temporal Operators and Constructs on page 669

13.11 =>
Purpose
Temporal yield operator

Category
Temporal expression

Syntax
temporal-expression1 => temporal-expression2
Syntax Example
@A => {[1..2]*@clk; @B}

Parameters
temporal-expression1

The first temporal expression. The second temporal expression is expected


to succeed if this expression succeeds.

Specman e Language Reference


1999-2015

687
.

Product Version 15.1


All Rights Reserved.

temporal-expression2

The second temporal expression. If the first temporal expression succeeds,


this expression is also expected to succeed.

Description
The yield operator is used to assert that success of one temporal expression depends on the success of
another temporal expression. The yield expression TE1 => TE2 is equivalent to (fail TE1) or {TE1 ;
TE2}.
The yield expression succeeds without evaluating the second expression if the first expression fails. If
the first expression succeeds, then the second expression must succeed in sequence.
Yield is typically used in conjunction with the expect struct member to express temporal rules.
The sampling event from the context applies to both sides of the yield operator expression. The entire
expression is essentially a single temporal expression, so that
(TE1 => TE2)@sampling_event

is effectively
(TE)@sampling_event

where TE is the temporal expression made up of TE1 => TE2.

Example
The following temporal expression succeeds if acknowledge occurs 1 to 100 cycles after request occurs.
(The {...;...} syntax specifies a temporal sequence. See { exp ; exp } on page 678 for information about
the ; sequence operator).
expect @request => {[..99]; @acknowledge};

See Also

expect on page 717

Temporal Operators and Constructs on page 669

Specman e Language Reference


1999-2015

688

Product Version 15.1


All Rights Reserved.

13.12 detach
Purpose
Detach a temporal expression

Category
Temporal expression

Syntax
detach(temporal-expression)
Syntax Example
@trans.end => detach({@trans.start; ~[2..5]})@pclk

Parameters
temporal-expression

A temporal expression to be independently evaluated.

Description
A detached temporal expression is evaluated independently of the expression in which it is used. It starts
evaluation when the main expression does. Whenever the detached TE succeeds it emits an implicit
event which will only be recognized by the main TE. The detached temporal expression inherits the
sampling event from the main temporal expression.

Example 1
In the following example, both S1 and S2 start with @Q. However, the S1 temporal expression expects
E to follow Q, while the S2 temporal expression expects E to precede Q by one cycle.
The detach() construct causes the temporal expressions to be evaluated separately. As a result, the S3
temporal expression is equivalent to the S2 expression. See Figure 13-6.
struct s {
event pclk is @sys.pclk;
event Q;
event E;
event T is {@E; [2]} @pclk;
event S1 is {@Q; {@E; [2]}} @pclk;
Specman e Language Reference
1999-2015

689
.

Product Version 15.1


All Rights Reserved.

event S2 is {@Q; @T} @pclk;


event S3 is {@Q; detach({@E; [2]})} @pclk;
};

Figure 13-6

Examples Illustrating Detached Temporal Expressions

pclk
Q
E
S1 is {@Q; {@E; [2]}}
T is {@E; [2]}
S2 is {@Q; @T}
S3 is {@Q; detach({@E; [2]})}

event emitted

evaluation starts

evaluation succeeds

evaluation fails

Example 2
Since a detached expression is evaluated independently and in parallel with the main temporal
expression the two events below are not the same:
event ev_a is {@TE1; {@TE1; @TE2}};
event ev_b is {@TE1; detach({@TE1; @TE2})};

The first expression is equivalent to:


event ev_a is {@TE1; @TE1; @TE2};

While the second is equivalent to:


event ev_b is {@TE1; @ev_c};
event ev_c is {@TE1; @TE2};

Specman e Language Reference


1999-2015

690

Product Version 15.1


All Rights Reserved.

Example 3
The following two expressions are equivalent:
fail detach({@ev_a; @ev_b})
not({@ev_a; @ev_b})

See Also

Temporal Operators and Constructs on page 669

13.13 delay
Purpose
Specify a simulation time delay

Category
Temporal expression

Syntax
delay(int: exp [time-unit: string])
delay (num: exp [time-unit: string])
Syntax Example
wait delay(3);
wait delay(10 ns);

Parameters
int

An integer expression or time expression no larger than 64 bits. The number specifies the
amount of simulation time to delay.

time-unit The time units are in the timescale used in the HDL simulator. If no time unit is given,
Specman uses the time units set for its timescale.

Specman e Language Reference


1999-2015

691
.

Product Version 15.1


All Rights Reserved.

num

A real number expression or realtime expression. The number specifies the amount of
simulation time to delay.
Note Do not write a delay that is more precise than the current Specman precision. For
example, if the Specman precision is 1 ps, requesting a delay of 1.2 ps will give unknown
results.

Description
Succeeds after a specified simulation time delay elapses. A callback to Specman occurs after the
specified time. A delay of zero succeeds immediately.
Attaching a sampling event to delay has no effect. The delay ignores the sampling event and succeeds
as soon as the delay period elapses.

Note

This expression is not legal in standalone mode. It can only be used if Specman is being run with an
attached HDL simulator.
The delay temporal expression is only supported for the cases:
wait delay(x);
event e is {@a;delay(x)};

Example 1
The following specifies a delay of 20 simulator time units:
wait delay(20);

Example 2
The following specifies a delay of df*5 simulator time units:
wait delay(df*5);

Example 3
The following specifies a delay of 5.66 simulator time units:
wait delay(5.66);

Example 4
The following use of the delay expression generates an error:

Specman e Language Reference


1999-2015

692

Product Version 15.1


All Rights Reserved.

//

event del_b is {@set_a; delay(10)} @clk;

// Load-time error

See Also

wait on page 728

verilog time on page 847

vhdl time on page 885

Temporal Operators and Constructs on page 669

13.14 @ unary event operator


Purpose
Use an event as a temporal expression

Category
Temporal expression

Syntax
@[struct-exp.]event-type
Syntax Example
wait @rst;

Parameters
struct-exp.event-type

The name of an event. This can be either a predefined event or a user-defined


event, optionally including the name of the struct instance in which the event
is defined.

Description
An event can be used as the simplest form of a temporal expression. The temporal expression
@event-type succeeds every time the event occurs. Success of the expression is simultaneous with the
occurrence of the event.

Specman e Language Reference


1999-2015

693
.

Product Version 15.1


All Rights Reserved.

The struct-exp is an expression that evaluates to the struct instance that contains the event instance. If no
struct expression is specified, the default is the current struct instance.

Note
If a struct expression is included in the event name, the value of the struct expression must not change
throughout the evaluation of the temporal expression.

Examples
In the following, pclk is a temporal expression:
@pclk

The predefined sys.any event occurs at every Specman tick. As a sampling event, use it as follows:
@sys.any

See Also

event on page 662

Using Predefined Events in Creating e Testbenches

Temporal Operators and Constructs on page 669

13.15 @ sampling operator


Purpose
Specify a sampling event for a temporal expression

Category
Temporal expression

Syntax
temporal-expression @event-name
Syntax Example
wait cycle @sys.reset;

Specman e Language Reference


1999-2015

694

Product Version 15.1


All Rights Reserved.

Parameters
temporal-expression

A temporal expression.

event-name

The sampling event.

Description
Used to specify the sampling event for a temporal expression. The specified sampling event overrides
the default sampling event.
Every temporal expression has a sampling event. The sampling event applies to all subexpressions of the
temporal expression. It can be overridden for a subexpression by attaching a different sampling event to
the subexpression.
A sampled temporal expression succeeds when its sampling event occurs with or after the success of the
temporal expression.
The sampling event for a temporal expression is one of the following, in decreasing precedence order:
1.

For any expression or subexpression, a sampling event specified with the @ binary event operator.

2.

For a subexpression, the sampling event inherited from its parent expression.

3.

For an expression in a TCM, the default sampling event of the TCM.

4.

If none of the above applies, the predefined sys.any event.

Examples
The reset event is sampled at the pclk event:
@reset @pclk

The reset event is sampled by the predefined sys.any event:


@reset @sys.any

Event ev_a occurs when the reset event occurs, sampled at the rclk event:
event ev_a is @reset @rclk;

The following is the same as event ev_b is @reset @sys.any:


event e_b is @reset;

Specman e Language Reference


1999-2015

695
.

Product Version 15.1


All Rights Reserved.

See Also

true(exp) on page 697

event on page 662

Using Predefined Events in Creating e Testbenches

Creating Sampling Events in Creating e Testbenches

Temporal Operators and Constructs on page 669

13.16 cycle
Purpose
Specify an occurrence of a sampling event

Category
Temporal expression

Syntax
cycle
Syntax Example
wait cycle;

Description
Represents one cycle of some sampling event. With no explicit sampling event specified, this represents
one cycle of the sampling event from the context (that is, the sampling event from the overall temporal
expression, or the sampling event for the TCM that contains the temporal expression). When a sampling
event is specified, as in cycle@sampling-event, this is equivalent to @sampling-event@sampling-event.
In the following, the event named sys.pclk is the sampling event for the TCM named proc(). The wait
cycle action is the same as wait @sys.pclk.
proc() @sys.pclk is { wait cycle; };

Note When the temporal expression [numeric-expression]@temporal-expression is shortened to


simply [numeric-expression], cycle is the assumed temporal expression. This means that the following
two lines of code are exactly equivalent:
Specman e Language Reference
1999-2015

696

Product Version 15.1


All Rights Reserved.

wait [10]@cycle;
wait [10];

See [ exp ] on page 681 for more information.

Example 1
The following event definition replicates sys.clk as the local clk for the struct:
event clk is cycle @sys.clk;

This is equivalent to event clk is @sys.clk @sys.clk. It is also equivalent to event clk is @sys.clk.

Example 2
The following expression succeeds as soon as ev_a occurs:
m_tcm() @ev_s is {
wait cycle @ev_a;
out("Done");
};

See Also

event on page 662

Using Predefined Events in Creating e Testbenches

Creating Sampling Events in Creating e Testbenches

@ sampling operator on page 694

Temporal Operators and Constructs on page 669

13.17 true(exp)
Purpose
Boolean temporal expression

Category
Temporal expression

Specman e Language Reference


1999-2015

697
.

Product Version 15.1


All Rights Reserved.

Syntax
true(bool: exp)
Syntax Example
event rst is true(reset == 1) @clk;

Parameters
bool

A Boolean expression.

Description
Use a Boolean expression as a temporal expression. Each occurrence of the sampling event causes an
evaluation of the Boolean expression. The Boolean expression is evaluated only at the sampling point.
The temporal expression succeeds each time the expression evaluates to TRUE.

Note
The expression exp will be evaluated after pclk. Changes in exp after true(exp) @pclk has been
evaluated will be ignored.

Example 1
The following causes the TCM to suspend until reset is high. The condition is checked for the first time
at the first occurrence of clk after the wait is encountered; it is then checked every clk cycle after that.
See wait on page 728.
notify_reset() @clk is {
wait true(reset == 1);
out("reset is 1");
};

Example 2
The temporal expression below succeeds when the Boolean condition sys.number_of_packets == 5
evaluates to TRUE at the default sampling event. Execution of the TCM containing the wait action
suspends until the Boolean condition is true.
wait true(sys.number_of_packets == 5);

Specman e Language Reference


1999-2015

698

Product Version 15.1


All Rights Reserved.

See Also

Boolean scalar type in Scalar Types on page 138

Creating Sampling Events in Creating e Testbenches

Temporal Operators and Constructs on page 669

13.18 change(exp), fall(exp), rise(exp)


Purpose
Transition or edge temporal expression

Category
Temporal expression

Syntax
change | fall | rise(scalar: exp) [@event-type]
change | fall | rise(simple-port$ | HDL-pathname) @sim
Syntax Example
event hv_c is change(sig_hv$)@sim;

Parameters
scalar

A Boolean expression or an integer expression.

event-type

The sampling event for the expression.

simple-port

A simple port bound to an HDL or SystemC object.

HDL-pathname

An HDL or SystemC object enclosed in single quotes (' ').

@sim

A special annotation used to detect changes in HDL or SystemC signals.

Description
Detects a change in the sampled value of an expression.

Specman e Language Reference


1999-2015

699
.

Product Version 15.1


All Rights Reserved.

The expression is evaluated at each occurrence of the sampling event, and is compared to the value it
had at the previous sampling point. Only the values at sampling points are detected. The value of the
expression between sampling points is invisible to the temporal expression.
The behavior of each of the three temporal expressions (change, fall, and rise) is described in Table
13-2.

Table 13-2

Edge Condition Options

Edge Condition

Object

Meaning

rise(exp)

Scalar

Boolean: Succeeds when the expression changes from FALSE to


TRUE.
Integer: Succeeds upon any change from x to y>x.
Integers larger than 32 bits are not allowed.

fall(exp)

DUT

Succeeds when the value of the object changes from 0 to 1.


Appropriate for detecting a rise on a 1-bit DUT signal.

Scalar

Boolean: Succeeds when the expression changes from TRUE to


FALSE.
Integer: Succeeds upon any change from x to y<x.
Integers larger than 32 bits are not allowed.

change(exp)

DUT

Succeeds when the value of the object changes from 1 to 0.


Appropriate for detecting a fall on a 1-bit DUT signal.

Scalar

Succeeds when the value of the expression changes. change()


succeeds upon any change of the expression.
Integers larger than 32 bits are not allowed.

DUT

Succeeds when the value of the expression changes. change()


succeeds upon any change of the expression.
Note The use of change() is appropriate for both 1-bit and
multi-bit DUT objects. However, DUT objects larger than 32 bits are
not allowed.

Specman e Language Reference


1999-2015

700

Product Version 15.1


All Rights Reserved.

The @sim Notation


A special notation, @sim, is used in place of a sampling event for rise, fall, or change of HDL or
SystemC objects. The @sim notation does not signify a Specman event, but is used only to cause a
callback to Specman any time there is a change in the value of the HDL or SystemC object to which it is
attached.
Figure 13-7 on page 701 illustrates why it is important to use @sim rather than another sampling event
to detect changes to an HDL object. In Figure 13-7 on page 701, evaluations of rise, fall, and change

expressions for the HDL signal V are shown, with the sampling event @sim and with the sampling
event @qclk. The qclk event is an arbitrary event that is emitted at the indicated points. The V signal
rises and then falls between the second and third occurrences of event qclk. Since the signals value is
the same at the third qclk event as it was at the second qclk event, the change('V')@qclk expression
does not succeed at the third qclk event.
Figure 13-7

Effects of the Sampling Rate on Detecting HDL Object Changes


'V'

change('V')@sim
rise('V')@sim
fall('V')@sim
qclk
change('V')@qclk
rise('V')@qclk
fall('V')@qclk

Use in Simulator Callbacks


The temporal expression change|rise|fall()@sim is used to create simulator callbacks, as illustrated in
the following code:
sig_p : inout simple_port of bit is instance;
keep sig_p.hdl_path() == "sig";
event sig_e is change (sig_p$)@sim;

This approach to creating callbacks lets you access the value of the changed DUT object during the
callback, as well as alerting Specman to the change in value.

Specman e Language Reference


1999-2015

701
.

Product Version 15.1


All Rights Reserved.

However, you get better performance when you use an event port combined with a simple port whereby
the event port detects the change and the simple port holds the changed value.
For more information about the pros and cons of using simple ports versus event ports to create
simulator callbacks, see Creating Simulator Callbacks in Creating e Testbenches.

Translation of HDL Values to Specman Values


When applied to DUT objects, the change() | fall() | rise() expressions examine the value after each bit
is translated from the DUT four-value or nine-value logic representation to the Specman two-value logic
representation.
Table 13-3 describes the default translation of HDL values to Specman values.

Table 13-3

Transition of HDL Values

HDL Values

Specman Value

0, X, U, W, L, -

1, Z, H

Notes

If you are using the HDL-pathname notation, you can use the @x and @z modifiers to override
the default translation. See 'HDL-pathname' on page 897 for more information.
If you need to track MVL transitions, you can use an event port with the edge() attribute, instead of
a simple port. See edge() in Specman Integrators Guide for more information.
For Verilog designs, you can use the === operator to detect a change between two-state and four-state
logic, as in the following:
change('top.hold_var' === two_state_hold_var)@clk;

Using change() | rise() | fall() @sim in TCMs with wait and synch
In TCMs it is preferred to use change()@sim, rise()@sim, and fall()@sim temporal expressions in a
sync action rather than a wait action:

When used in a sync action, the monitoring of changes in signal value begins immediately and
includes changes in subsequent delta cycles in the current simulation time.
When used in a wait action, the monitoring of changes in signal value begins in the next simulation
time.

In both actions, the initial value of the signal is sampled as soon as the sync or wait action is reached.
Specman e Language Reference
1999-2015

702

Product Version 15.1


All Rights Reserved.

For example, if a TCM uses


sync rise('my_sig')@sim;

and if the value of 'my_sig' falls in a later delta-cycle of the same simulation time as the sync action is
reached, Specman records the change of the value and could observe a rise in the following simulation
time.
However if the TCM uses
wait rise('my_sig')@sim;

and the value of a signal 'my_sig' falls in a later delta-cycle of the same simulation time as the wait
action is reached, this fall is not observed by the temporal expression. Consequently, the next rise of the
value of the 'my_sig' signal is ignored by the temporal expression as a change in the signal value that did
not rise with respect to the signal's value at the time the wait action was reached.

Handling Glitches
Specman ignores glitches that occur in a single simulation time slot. Only the first occurrence of a
particular monitored event in a single simulation time slot is recognized by Specman. For example, if a
signal transitions from 0 to 1 and back to 0 in the same time slot, Specman sees only the 0 to 1 transition;
the 1 to 0 transition is ignored.
For information on how to handle glitches, see:

How Specman Handles Glitches in a Single Simulation Time Slot in Understanding Simulation
Time and Specman Ticks in Creating e Testbenches.
Dealing with Glitches in Callbacks in Creating e Testbenches

Examples
The following defines an event that occurs at any change in the value of an HDL signal named top.clk:
event clk_c is change('top.clk')@sim;

The following defines an event that occurs when the Boolean expression pkt_size > 20 changes from
FALSE to TRUE:
event big_pkt is rise(pkt.size > 20);

The following defines an event that occurs at a fall in the value of an HDL signal named ~/top/reset,
sampled by an event named rsmp:
event rst is fall('~/top/reset')@rsmp;

Specman e Language Reference


1999-2015

703
.

Product Version 15.1


All Rights Reserved.

See Also

Creating Sampling Events in Creating e Testbenches

Creating Simulator Callbacks in Creating e Testbenches

'HDL-pathname' on page 897

Reading and Writing HDL Objects in the Specman Integrators Guide

Temporal Operators and Constructs on page 669

Sampling SystemC Signals by Using @sim in the Specman Integrators Guide

13.19 consume
Purpose
Consume an occurrence of an event

Category
Temporal expression

Syntax
consume(@event-type)
Syntax Example
sync consume(@counter);
wait consume(@done)@sys.any;

Parameters
event-type

The name of the event that is to be consumed.

Description
Removes the occurrence of an event so that it is not available for other temporal expressions. The
consume expression succeeds whenever the event occurs. If the event occurs more than once during any
given cycle, all occurrences are consumed.
After an event occurrence is consumed, that occurrence will not be recognized by any temporal
expression during the current Specman tick, unless the event is emitted again.
Specman e Language Reference
1999-2015

704

Product Version 15.1


All Rights Reserved.

An event cannot be consumed by more then one consume expression. Care should be used to avoid
creating race conditions between multiple events that use an event that is consumed.

Notes

The consume(@event-type) temporal expression can only be used in one of the following time
consuming actions:
sync consume(@event-type) [@sampling_event];
wait consume(@event-type) [@sampling_event];

When an optional sampling event is specified, then the sync or wait action finishes with the first
occurrence of the sampling event after the consume succeeds.
If no sampling event is specified, the default sampling event of the TCM applies.

An event can either be used in a consume(@event-type) expression or be used in another temporal


expression, but not in both.

Example
The following code shows how you can use consume() to handle concurrent requests from multiple
clients in an orderly manner.
The example enables the following behaviors:

The requests are granted on a First-In-First-Out basis.

A client may hold the grant for several Specman cycles.

The server can accumulate requests during several Specman cycles.

Multiple clients requests can be granted sequentially at the same Specman time.

In this example there are four client structs and one server struct. The server ensures that all requests are
granted and that there are no simultaneous grants.
When multiple clients issue a request at the same time the server is using a counter to keep track of the
number of requests. The server consumes all the requests, and then issues a grant event. The first client
to issue a request consumes the grant, making it unavailable to the other clients. When this client is done
with the grant it issues a done event. The server consumes the done event and issues a release event. The
release event is consumed by the client. The server repeats this process until the request counter is zero.
<'
struct server {
event clk is rise('top.clock');
event request;
event grant;
event done;
event release;
Specman e Language Reference
1999-2015

705
.

Product Version 15.1


All Rights Reserved.

!req_counter: int;
on request {
req_counter += 1;
out("req_counter = ", req_counter);
};
serv() @clk is {
while TRUE {
if (req_counter == 0 || now @request) {
sync consume(@request);
out("Requests consumed...");
};
req_counter -= 1;
emit grant;
sync consume(@done);
emit release;
};
};
run() is also {start serv();};
};
struct client {
id: string;
s: server;
handshake() @s.clk is {
// Zero delay handshake
out(id, ": Starting handshake at time ", sys.time);
emit s.request;
sync consume(@s.grant);
out(id, ": Granted, releasing");
emit s.done;
sync consume(@s.release);
};
run() is also {start handshake();};
};
extend sys {
event clk;
s: server;
c1: client;
c2: client;
c3: client;
c4: client;

keep
keep
keep
keep

{
{
{
{

c1.s==s;
c2.s==s;
c3.s==s;
c4.s==s;

c1.id=="client
c2.id=="client
c3.id=="client
c4.id=="client

1"
2"
3"
4"

};
};
};
};

go()@any is {
for i from 0 to 40 do {
wait cycle;

Specman e Language Reference


1999-2015

706

Product Version 15.1


All Rights Reserved.

emit clk;
};
stop_run();
};
run() is also {start go()};
};
'>

Result
Running the test ...
client 1: Starting handshake at time 1
req_counter = 1
client 2: Starting handshake at time 1
req_counter = 2
client 3: Starting handshake at time 1
req_counter = 3
client 4: Starting handshake at time 1
req_counter = 4
Requests consumed...
client 1: Granted, releasing
client 2: Granted, releasing
client 3: Granted, releasing
client 4: Granted, releasing
Last specman tick - stop_run() was called
Normal stop - stop_run() is completed

See Also

event on page 662

Temporal Operators and Constructs on page 669

13.20 exec
Purpose
Attach an action block to a temporal expression

Specman e Language Reference


1999-2015

707
.

Product Version 15.1


All Rights Reserved.

Category
Temporal expression side effect

Syntax
temporal-expression exec action; ...
Syntax Example
wait @watcher_on exec {print watcher_status_1;};

Parameters
temporal-expression

The temporal expression that invokes the action block.

action

A series of actions to perform when the expression succeeds.


Note

The action block cannot contain any time-consuming actions.

Description
Invokes an action block when a temporal expression succeeds. The actions are executed immediately
upon the success of the expression, but not more than once per Specman tick.
To support extensibility of your e code, use method calls in the exec action block rather than calling the
actions directly.
The usage of exec is similar to the on struct member, except that:

Any temporal expression can be used as the condition for exec, while only an event can be used as
the condition for on.
exec must be used in the context of a temporal expression in a TCM or an event definition, while on
can only be a struct member.

Notes

You cannot attach an exec action to a first match of a first match variable repeat expression:
([7..10] *@b) exec {out("in exec")}

-- is not allowed

However, you can attach an exec action to the repeat expression of a first match variable repeat
expression as follows:
[7..10] *@b exec {out("in exec")}
-- is allowed
[7..10] * (@b exec {out("in exec")}) -- is allowed

Specman e Language Reference


1999-2015

708

Product Version 15.1


All Rights Reserved.

The two expressions above are equivalent. They both execute the exec action once for each
occurrence of b.

You cannot attach an exec action to an implicit repeat expression:


expect @e => {
[..20];
-- exec is not allowed here
@a;
};

You must make the implicit repeat expression explicit in order to attach an exec action:
expect @e => {
[..20] * (cycle exec {out("in exec")}); -- is allowed
@a;
};

When the numeric argument of the repeat temporal-expression is not a literal such 1 or 4K, the
repeat numeric argument is evaluated one cycle before the repeat sub-expression is reached. See
Example 2 on page 709.

Example 1

Pipeline

The following code maintains a pipeline of instruction instances.


struct pipelined_alu {
instructions: list of inst;
ck_inst: inst;
event alu_watcher is {
rise('inst_start') exec {
var i: inst = new;
instructions.add(i);
};
[..];
rise('inst_end') exec {
ck_inst = instructions.pop()
}
}@sys.alu.aclk;
};

Example 2

Sampling of Repeat Expression

In this example, there are four events, A, B, C and D. Two of the events, A and B, assign a variable
(A_Length or B_Length) and then use that variable in a repeat expression. At first glance, you might
assume that events A and B are emitted at exactly the same moment.
<'
extend sys {
Specman e Language Reference
1999-2015

709
.

Product Version 15.1


All Rights Reserved.

A_Length : int; keep A_Length == 1;


B_Length : int; keep B_Length == 1;
event
event
event
event

A is {@C exec {A_Length = 2;};cycle;[A_Length]*@D};


B is {@C;cycle exec {B_Length = 2;};[B_Length]*@D};
C;
D;

run() is also {
start main();
};
main() @any is {
emit C;
wait;
wait;
emit D;
wait;
emit D;
wait;
stop_run();
};
setup() is also {
specman("trace event sys.A,sys.B,sys.C,sys.D");
};
};
'>

Results
However, the variable in the repeat expression (A_Length or B_Length) is evaluated in cycle 1, one
cycle before the repeat expression is reached in cycle 2. In cycle 1, A_Length already has the value 2,
but B_Length is still 1. Thus event B happens in cycle 2, but event A does not happen until cycle 3.
Starting the test ...
Running the test ...
--------------------------------------------------> 0 sys-@0.C
--------------------------------------------------> 2 sys-@0.D
-> 2 sys-@0.B
--------------------------------------------------> 3 sys-@0.D
-> 3 sys-@0.A
Last specman tick - stop_run() was called
Normal stop - stop_run() is completed
Checking the test ...
Specman e Language Reference
1999-2015

710

Product Version 15.1


All Rights Reserved.

Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

Action blocks, described in Actions on page 46

on event on page 713

Temporal Operators and Constructs on page 669

Specman e Language Reference


1999-2015

711
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

712

Product Version 15.1


All Rights Reserved.

14

Temporal Struct and Unit


Members

In addition to the event struct member (see event on page 662), there are several other struct or unit
members used for temporal coding:

on event on page 713

on event-port on page 716

expect on page 717

See Also

Invoking Methods on page 535

Chapter 12 Events

Chapter 13 Temporal Expressions

Chapter 15 Time-Consuming Actions

Working with Events in Creating e Testbenches

14.1 on event
Purpose
Specify a block of actions that execute on an event

Specman e Language Reference


1999-2015

713
.

Product Version 15.1


All Rights Reserved.

Category
Struct or unit member

Syntax
on [const-exp.]event-type {action; ...}
Syntax Example
on xmit_ready {transmit();};

Parameters
const-exp

An optional expression identifying the struct or unit in which the event is defined. This
expression must remain constant and thus can consist only of:

A const field
A unit instance name
Indexing a unit from a list of unit instances (a constant unit pointer)

If not provided, the context struct or unit is assumed.


event-type

The name of an event that invokes the action block.

action; ...

A block of non-time-consuming actions.

Description
Defines a struct or unit member that executes a block of actions immediately whenever a specified event
occurs. An on struct or unit member is similar to a regular method except that the action block for an on
struct or unit member is invoked immediately upon an occurrence of the event. An on action block is
executed before TCMs waiting for the same event.
You can extend an on struct or unit member by repeating its declaration, with a different action block.
This has the same effect as using is also to extend a method.
If no const-struct-ext is specified (that is, the event is declared for the context struct), the on struct
member is available also as a regular method, named on_event-type(). In this case, you can invoke the
action block without the occurrence of the event by calling the on_event-type() method. You can extend
the on_event-type() method like any other method, using is, is also, is only, or is first.

Notes

The on action block must not contain any time-consuming actions.

Specman e Language Reference


1999-2015

714

Product Version 15.1


All Rights Reserved.

The on remains active throughout the lifetime of the object from its creation until either quit() is
called or the run ends. Garbage collection does not occur before quit() has been called.

See Also

Order of What Happens During a Specman Tick in Creating e Testbenches

Example 1
struct cnt_e {
event ready;
event start_count;
on ready {sys.req = 0};
on start_count {
sys.count = 0;
sys.counting = 1;
out("Starting to count");
};
};

Example 2
The following example shows how to invoke an on action block using an event that is defined in a
different struct.
<'
extend sys {
event clk is change('top.clk') @sim;
// system clock
card_i: card;
};
struct card {
on sys.clk {
out("clock tick");
};
};
'>

See Also

on event-port on page 716

event on page 662

Action block, in Actions on page 46

method [@event] is also | first | only on page 525

Specman e Language Reference


1999-2015

715
.

Product Version 15.1


All Rights Reserved.

14.2 on event-port
Purpose
Specify a block of actions that execute on the triggering of an event port

Category
Unit member

Syntax
on [const-unit-exp.]event-port-name$ {action; ...}
Syntax Example
on sys.clk$ {transmit();};

Parameters
const-unit-exp

An optional expression identifying the unit in which the event port is defined. This
expression must remain constant and thus can consist only of:

A const field
A unit instance name
Indexing a unit from a list of unit instances (a constant unit pointer)

If not provided, the context unit is assumed.


event-port-name

The event port that invokes the action block. The port direction must be either in or
inout.

action; ...

A block of non-time-consuming actions.

Description
Defines a unit member that executes a block of actions immediately whenever the specified event port is
triggered. An on unit member is similar to a regular method except that the action block for an on unit
member is invoked immediately when the event port is triggered. An on action block is executed before
TCMs waiting for the same event.

Specman e Language Reference


1999-2015

716

Product Version 15.1


All Rights Reserved.

Notes

The on action block must not contain any time-consuming actions.


The on remains active throughout the lifetime of the object from its creation until either quit() is
called or the run ends. Garbage collection does not occur before quit() has been called.
The execution order of on blocks associated with an event port is the order in which the different
objects defining them are created. Within the same object, the order of execution is according to the
order of definition in the code.

Example
extend sys {
clk: in event_port is instance;
keep bind(ext_ep,external);
};
struct card {
on sys.clk$ {
out("clock tick");
};
};

See Also

Event Port Declarations, References, and Access Operator on page 404

Action block, in Actions on page 46

Creating Simulator Callbacks in Creating e Testbenches

14.3 expect
Purpose
Define a temporal behavioral rule

Category
Struct or unit member

Specman e Language Reference


1999-2015

717
.

Product Version 15.1


All Rights Reserved.

Syntax
The following syntax defines an expect struct member for the first time:
expect [rule-name is ] temporal-expression
[else dut_error(string-exp)]
[using temporal-operators]
The following syntax modifies a named, existing expect struct member, via is only and/or using also:
expect rule-name [is only temporal-expression [else dut_error(string-exp)]]
[using also temporal-operators]
Syntax Example
expect @a => {[1..5];@b} @clk;

Parameters
rule-name

An optional name that uniquely identifies the rule from other rules or events
within the struct or unit. You can use this name to override the temporal rule later
on in the code.

temporal-expression A temporal expression that is always expected to succeed. Typically involves a


temporal yield (=>) operation.
string-exp

A string or a method that returns a string. If the temporal expression fails, the
string is printed, or the method is executed and its result is printed.

Specman e Language Reference


1999-2015

718

Product Version 15.1


All Rights Reserved.

temporal-operators

You can specify up to three temporal opterators. Each operator consists of two
parts: operation, and a condition. Upon detection of the condition, the operation is
performed.
The following are possible operations:
abort

Terminate evaluation of the temporal expression in the current


tick, and restart it in the next simulation time.

[exclusive_]start start and exclusive_start both start the evaluation of the


temporal expression in the current tick if the expect is currently
in a stopped state.
Furthermore, exclusive_start also means that the expect is
stopped when the struct is created, and remains stopped until
acted upon by the exclusive start.
stop

Stop the evaluation of the temporal expression in the current


tick. It will remain stopped until a start instruction is issued.

The following are possible conditions:


@event-name

Triggering temporal event. This event can be in the same struct


(that is, [me.]event-name), or reachable via a constant path
(that is, const-or-unit-instance-field-path.event-path).

none

Return to the default state. This value is intended for use when
there was a previous triggering event for this instruction that
should be removed.

empty

Used to specify a dummy event (i.e., an event that never


happens), for use with the procedural API. (For more
information, see Scheduler Methods on page 1260.)

Description
Expect struct or unit members define temporal rules. If the temporal expression fails at its sampling
event, the temporal rule is violated and an error is reported. If there is no dut_error() clause, the rule
name is printed.
Temporal operators can be attributed to a named or anonymous expect with using syntax in a definition,
or using also in a redefinition of a named expect, or added as a separate extension to an existing expect
with using also.
Once a rule has been defined, it can be modified using the is only syntax. You can perform multiple
verification runs either varying the rules. See the examples below for information on how to do this.
Specman e Language Reference
1999-2015

719
.

Product Version 15.1


All Rights Reserved.

Notes

You can introduce an abstract or empty expect that can later be overridden, by specifying
true(TRUE) as its temporal expression. Such an expect holds true at all time, has no effect on the
run, is recognized like other expects (for example, by the reflection API and the set checks command),
and does not introduce performance overhead. (See Example 4 on page 721.)
The is also, is undefined, and is empty forms are not supported for this construct.
You can use two reflection methodsrf_expect.stop(instance) and rf_expect.rerun(instance)to
start and stop expects. These methods are primarily intended for use during the rerun phase mechanism
when creating a UVM e testflow. They are described in Using Testflow Phases in the UVM e User
Guide.

Example 1
This example defines an expect, bus_cycle_length, which requires that the length of the bus cycle be
no longer than 1000 cycles.
struct bus_e {
event bus_clk is change('top.b_clk') @sim;
event transmit_start is rise('top.trans') @bus_clk;
event transmit_end is rise('top.transmit_done') @bus_clk;
event bus_cycle_length;
expect bus_cycle_length is
@transmit_start => {[0..999];@transmit_end} @bus_clk
else dut_error("Bus cycle did not end in 1000 cycles");
};

Result
If the bus cycle is longer than 1000 cycles, the following message will be issued.
------------------------------------------------------*** Dut error at time 1000
Checked at line 7 in @expect_msg
In bus_e-@0:
bus_cycle_length: Bus cycle did not end in 1000 cycles
------------------------------------------------------Will stop execution immediately (check effect is ERROR)
*** Error: A Dut error has occurred

Specman e Language Reference


1999-2015

720

Product Version 15.1


All Rights Reserved.

Example 2
In this example, the bus_e struct from Example 1 on page 720 is extended and two subtypes are
created, Slow and Fast. For the Fast subtype, the bus_cycle_length is modified to be shorter. e
inheritance allows subtypes to override rules defined in the base struct using the is only syntax.
extend bus_e {
type: [Slow, Fast];
when Fast bus_e {
expect bus_cycle_length is only
@transmit_start => {[0..99]; @transmit_end} @bus_clk
else dut_error("Bus cycle did not end \
within 100 cycles");
};
};

Example 3
In this example, the bus_e struct from Example 1 on page 720 and Example 2 on page 721 is
extended. The abort operator is added to the bus cycle rule.
<'
struct bus_e {
event bus_clk is change('top.b_clk') @sim;
event transmit_start is rise('top.trans') @bus_clk;
event transmit_end is rise('top.transmit_done') @bus_clk;
expect bus_cycle_length is
@transmit_start => {[0..999];@transmit_end} @bus_clk
else dut_error("Bus cycle did not end in 1000 cycles");
};
extend bus_e {
event bus_reset;
expect bus_cycle_length using also abort @bus_reset;
};
extend sys {
bus_e;
};
'>

Example 4
This example uses true(TRUE) as a temporal expression to create an abstract expect (my_expect) that
later gets filled in.
<'
type color_t: [RED, GREEN, BLUE];
struct packet {
color: color_t;
Specman e Language Reference
1999-2015

721
.

Product Version 15.1


All Rights Reserved.

expect my_expect is true(TRUE);


};
extend RED packet {
event transmit_start;
event transmit_end;
expect my_expect is only @transmit_start => {[0..99]; @transmit_end};
};
'>

Example 5
In the following example, two expect statements are used to specify that the transmit_end event must
occur within three to six bus_clk cycles after the transmit_start event. If fewer than three cycles
occur, the DRV_SHORT err_id is passed to the m_error() method. If more than six cycles occur, the
DRV_LONG err_id is passed to the method. The m_error() method adds one to the error_count
value, and returns a string that states which type of error occurred.
<'
type watcher_errors :[DRV_LONG, DRV_SHORT];
// Enumerated error conditions
extend sys {
event clk is @sys.any;
event start_drive;
event stop_drive;
!error_count: int; // Counts number of errors
my_watcher: watcher;
};
struct watcher {
expect @sys.start_drive =>
[2] * not @sys.stop_drive @sys.clk
else dut_error("Drive Rule 1: ",
m_error(DRV_SHORT));
expect @sys.start_drive =>
{[..5];@sys.stop_drive}@sys.clk
else dut_error("Drive Rule 1: ",
m_error(DRV_LONG));
m_error(err_id: watcher_errors):string is {
case err_id {
DRV_LONG: {
result = "Driving strobe too long";
sys.error_count += 1;
};
DRV_SHORT: {
result = "Driving strobe too short";
Specman e Language Reference
1999-2015

722

Product Version 15.1


All Rights Reserved.

sys.error_count += 1;
};
default: { result = "No error"; };
};
};
};
'>

See Also

Chapter 13 Temporal Expressions, in particular, => on page 687

English-to-Temporal Dictionary for Check Phrases in Creating e Testbenches

Specman e Language Reference


1999-2015

723
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

724

Product Version 15.1


All Rights Reserved.

15

Time-Consuming Actions

This chapter contains the following sections:

Synchronization Actions on page 725

Concurrency Actions on page 730

See Also

Invoking Methods on page 535

Chapter 12 Events

Chapter 13 Temporal Expressions

Chapter 14 Temporal Struct and Unit Members

15.1 Synchronization Actions


The following actions are used to synchronize temporal test activities within Specman and between the
DUT and Specman:

sync on page 725

wait on page 728

15.1.1

sync

Purpose
Synchronize an executing TCM

Specman e Language Reference


1999-2015

725
.

Product Version 15.1


All Rights Reserved.

Category
Action

Syntax
sync [temporal-expression]
Syntax Example
sent_data_tcm();
sync;

Parameters
temporal-expression

A temporal expression that specifies what the TCM synchronizes to.

Description
Suspends execution of the current TCM until the temporal expression succeeds. Evaluation of the
temporal expression starts immediately when the sync action is reached. If the temporal expression
succeeds within the current Specman tick, the execution continues immediately.
Note

Specman evaluates the temporal expression only once, when the sync action is first evaluated.

If no temporal expression is provided, the TCM synchronizes to its default sampling event. The TCM
suspends until the occurrence of its sampling event, or continues immediately if the sampling event
succeeds in the current Specman tick.
You can use the sync action after a call to another TCM to align the continuation of the calling TCM
with its sampling event when the called TCM returns.
Execution of a thread is atomic: it cannot be interrupted except by a sync action or a wait action. When
one of those actions is encountered, control can be passed from the TCM to other TCMs.
The sync action is similar to the wait action, except that a wait action always requires at least one cycle
of the TCMs sampling event before execution can continue. With a sync action, execution can continue
in the same Specman tick.

Example
In the following example, the wait action in the driver() TCM causes at least a one-cycle delay, since
the true() temporal expression is evaluated for the first time at the next occurrence of the sampling
event. The wait consumes one occurrence of the clk event, and then execution of the TCM continues
at the second occurrence of clk.
Specman e Language Reference
1999-2015

726

Product Version 15.1


All Rights Reserved.

On the other hand, the sync action in the shadow() TCM does not result in a delay if its true temporal
expression succeeds immediately. Execution of the TCM continues at the next occurrence of the clk
event.
<'
struct data_drive {
event clk is rise('top.clk') @sim;
data: list of int;
driver() @clk is {
for each in data {
wait true('top.data_ready'== 1);
// Will not fall through, even if the condition
// holds when the wait is reached.
'top.in_reg' = it;
};
stop_run();
};
shadow() @clk is {
while TRUE {
sync true('top.data_ready' == 0);
// If the condition holds, the sync falls through.
out("Shadow read ", 'top.in_reg');
wait cycle;
// This wait is necessary to prevent
// an infinite loop.
};
};
run() is also {
start driver();
start shadow();
};
};
'>

See Also

event on page 662

Creating Sampling Events in Creating e Testbenches

Chapter 13 Temporal Expressions

wait on page 728

Specman e Language Reference


1999-2015

727
.

Product Version 15.1


All Rights Reserved.

15.1.2

wait

Purpose
Wait until a temporal expression succeeds

Category
Action

Syntax
wait [[until] temporal-expression]
Syntax Example
wait [3]*cycle;

Parameters
temporal-expression

A temporal expression that specifies what the TCM is to wait for.

Description
Suspend execution of the current time-consuming method until a given temporal expression succeeds. If
no temporal expression is provided, the TCM waits for its default sampling event. The until option is for
users who find that it clarifies what the wait action does. The option has no effect on the results of the
action.
Note

Specman evaluates the temporal expression only once, when the wait action is first evaluated.

When a VHDL or Verilog simulator is linked to Specman, the syntax wait delay(exp) can be used to
wait for a specific simulation time period. Because not all simulators support delay values greater than
32 bits, the value of the expression in wait delay(exp) cannot exceed 32 bits. A wait delay(exp) is
influenced by the timescale. See verilog time on page 847 and vhdl time on page 885 for more
information on how Specman determines the timescale.
The TCM cannot continue during the same cycle in which it reaches a wait, unless the temporal
expression evaluates to 0. That is, if the temporal expression evaluates to [0] * something, execution
can continue in the same cycle.

Specman e Language Reference


1999-2015

728

Product Version 15.1


All Rights Reserved.

If the wait actions temporal expression contains a variable subexpression, such as wait [var1 + var2] *
cycle, the subexpression is only evaluated once, when the wait is encountered. Any changes in the
value of the subexpression during subsequent cycles are ignored.
Execution of a thread is atomic: it cannot be interrupted except by a wait action or a sync action. When
one of those actions is encountered, control can be passed from the TCM to other TCMs.
The wait action is similar to the sync action, except that a wait action always requires at least one cycle
of the TCMs sampling event before execution can continue (unless a wait of zero is specified). With a
sync action, execution can continue immediately upon encountering the sync, if the temporal expression
succeeds at that time Seesync on page 725 for an example comparing the behavior of sync and wait.

Example 1
Several examples of temporal expressions for wait actions are shown below:
wait [3]*cycle;
// Continue on the fourth cycle from now
wait delay(30);
// Wait 30 simulator time units
wait [var1 + var2]*cycle;
// Calculate the number of cycles to wait
wait until [var1 + var2]*cycle;
// Same as wait [var1 + var2]*cycle
wait true(sys.time >= 200);
// Continue when sys.time is greater than or equal to 200
wait cycle @sys.reset;
// Continue on reset even if it is not synchronous with
// the TCMs default sampling event
wait @sys.reset;
// Continue on the next default sampling event after reset

Example 2
In the following example, the wait action in the driver() TCM causes a one-cycle delay even if the
true temporal expression succeeds immediately. The wait consumes one occurrence of the clk event,
and then execution of the TCM continues at the second occurrence of clk.
<'
struct data_drive {
event clk is rise('top.clk') @sim;
data: list of int;
driver() @clk is {
for each in data {
wait true('top.data_ready'== 1);
'top.in_reg' = it;
Specman e Language Reference
1999-2015

729
.

Product Version 15.1


All Rights Reserved.

};
stop_run();
};
run() is also {
start driver();
};
};
'>

See Also

delay on page 691

event on page 662

Creating Sampling Events in Creating e Testbenches

Chapter 13 Temporal Expressions

sync on page 725

15.2 Concurrency Actions


The actions that control concurrent execution of time-consuming methods are described in this section:

all of on page 730

first of on page 732

Both of these actions create parallel action blocks which might start or call TCMs. The first action
awaits completion of all branches, while the second terminates at the first completion of any branch.
Control of individual branches or TCMs can also be accomplished using predefined methods of the
predefined scheduler struct.

15.2.1

all of

Purpose
Execute action blocks in parallel

Category
Action

Specman e Language Reference


1999-2015

730

Product Version 15.1


All Rights Reserved.

Syntax
all of {{action; ...}; ... }
Syntax Example
all of { {block_a}; {block_b}; };

Parameters
{action; ...}; ...

Action blocks that are to execute concurrently. Each action block is a separate branch.

Description
Execute multiple action blocks concurrently, as separate branches of a fork. The action following the all
of action will be reached only when all branches of the all of have been fully executed. All branches of
the fork are automatically joined at the termination of the all of action block.

Example 1
Execute the following three TCMs concurrently, and continue after they all have finished:
all of {
{check_bus_controller();};
{check_memory_controller();};
{wait cycle; check_alu();};
};

Example 2
The all of construct can be used to wait for several events, no matter what order they arrive in. This can
be used as an AND relation between events as shown below.
<'
extend sys {
event aclk is @any;
event a;
event b;
detect_all() @aclk is {
all of {
{ wait @a; };
{ wait @b; };
};
out("Both a and b occurred");
};
Specman e Language Reference
1999-2015

731
.

Product Version 15.1


All Rights Reserved.

};
'>

See Also

first of on page 732

15.2.2

first of

Purpose
Execute action blocks in parallel

Category
Action

Syntax
first of {{action; ...}; ... }
Syntax Example
first of { {wait [3]*cycle@ev_a}; {wait @ev_e; }; };

Parameters
{action; ...}; ...

Action blocks that are to execute concurrently. Each action block is a separate branch.

Description
Execute multiple action blocks concurrently, as separate branches of a fork. The action following the
first of action will be reached when any of the branches in the first of has been fully executed. All
branches of the fork are automatically joined at the termination of the first of action block.
The parallel branches can be thought of as racing each other until one completes. Once one branch
terminates, Specman terminates the execution of each of the other branches.
When two branches finish executing during the same cycle, it is not possible to determine which will
prevail. One will complete successfully and the other will terminate.

Specman e Language Reference


1999-2015

732

Product Version 15.1


All Rights Reserved.

Example 1
The first of construct can be used in order to wait for one of several events. This can be used as an OR
relation between events:
<'
extend sys {
event c;
event d;
event fclk is @any;
detect_first() @fclk is {
first of {
{ wait @c; };
{ wait @d; };
};
out("Either c or d occurred");
};
};
'>

Example 2
The all of and first of actions can be used together to combine wait actions. In the following, the first of
action block terminates when event2 is seen:
<'
struct tcm_struct {
event clk is @sys.any;
event event1;
event event2;
main() @clk is {
all of {
{wait [10] * cycle;
emit event1;
emit event2;
out("Branch #1 done");};
{first of {
{wait @event1; out("Branch #2-1 done"); };
{wait @event2; out("Branch #2-2 done"); };
// One of the branches will never print
};
};
};
stop_run();
};
};
'>

Specman e Language Reference


1999-2015

733
.

Product Version 15.1


All Rights Reserved.

Example 3
In the following example, first of is used to create two branches, one of which continues after a
sys.reset event, and the other of which calls a method named sys.pdata() and then waits one cycle.
The number of cycles required by the pdata() method is the main factor in determining which branch
finishes first.
<'
struct mv_data {
data: int;
mdata() @sys.clk is {
first of {
{wait cycle @sys.reset;};
{sys.pdata(); wait cycle;};
};
stop_run();
};
run() is also {
start mdata();
};
};
'>

See Also

all of on page 730

Specman e Language Reference


1999-2015

734

Product Version 15.1


All Rights Reserved.

16

Coverage Constructs

This chapter contains the following sections:

Defining Coverage Groups on page 735

Defining Basic Coverage Items on page 745

Defining Cross Coverage Items on page 769

Defining Transition Coverage Items on page 785

Extending Coverage Groups on page 798

Extending Coverage Items on page 805

Collecting check/expect Results for Your Model on page 813

Coverage API Methods on page 818

16.1 Defining Coverage Groups


16.1.1

cover

Purpose
Define a coverage group

Category
Struct member

Specman e Language Reference


1999-2015

735
.

Product Version 15.1


All Rights Reserved.

Syntax
cover event-type [using coverage-group-option, ...] is {coverage-item-definition; ...};
cover event_type is empty;
Syntax Example
cover inst_driven is {
item opcode;
item op1;
cross opcode, op1;
};

Parameters
event-type

The name of the group. This must be the name of an event type defined
previously in the struct. The event must not have been defined in a subtype.
The event is the sampling event for the coverage group. Coverage data for the
group is collected every time the event occurs.
The full name of the coverage group is struct-exp.event-name. The full name
must be specified for the show cover command and other coverage commands
and methods.

coverage-groupoption

The coverage group options listed in Table 16-1 can be specified with the using
keyword.
Each coverage group can have its own set of options. The options can appear in
any order after the using keyword.

coverage-itemdefinition

The definition of a coverage item. Coverage items are described in Defining


Basic Coverage Items on page 745.
Note You can define a coverage group without defining any coverage items.
However, the coverage group does not appear in the coverage browser.

is also

See Extending Coverage Groups on page 798.

is empty

The empty keyword can be used to define an empty coverage group that will be
extended later, using a cover is also struct member with the same name.

Specman e Language Reference


1999-2015

736

Product Version 15.1


All Rights Reserved.

Table 16-1

Coverage Group Options

Option

Description

global=bool

When global[=TRUE], this coverage group is defined as a global group.


A global coverage group is a group whose sampling event is expected to
occur only once. If the sampling event occurs more than once, Specman
issues a DUT error. If items from a global group are used in interactive
cross coverage, no timing relationships exist between the items.
You can use using also global=FALSE to override a previous
global[=TRUE] setting.

instance_no_collect=e
xpr

Define a context-dependent no_collect expression in per_unit_instance


groups. This option lets you set no_collect expressions for an instance,
depending on the scope.
The expr argument for instance_no_collect can include an inst field. In
the context of an explicit per-unit instance or for cover groups defined
under a struct or unit, the inst field contains a pointer to the unit defined
by the per_unit_instance option. In the case of an implicit per-unit
instance collection of cover groups defined under units, the inst field
refers to the enclosing unit.
When an instance_no_collect expression is defined, its unit type must be
known and cannot change after the definition. As a result:

no_collect=bool

For a cover group defined inside a struct, an instance_no_collect


expression cannot be defined before the per_unit_instance is defined
for the cover group.
After an instance_no_collect expression is defined for a cover group,
the per_unit_instance type cannot be changed.

When no_collect[=TRUE], this coverage group is not displayed in


coverage reports and is not saved in the coverage files. This option
enables tracing of coverage information and enables event viewing with
trace event, without saving the coverage information. Setting this option
to TRUE overrides the global config cover mode setting.
You can use using also no_collect=FALSE to override a previous
no_collect[=TRUE] setting.

Specman e Language Reference


1999-2015

737
.

Product Version 15.1


All Rights Reserved.

Table 16-1

Coverage Group Options, continued

Option

Description

per_unit_instance
[=unit-type]

To create cover group instances, you can define a cover group either in a
unit or in a struct nested in a unit. If the cover group is defined in a struct,
you must specify the unit-type of the structs enclosing unit in the
per_unit_instance option. If the cover group is declared in a unit, the
unit-type in the per_unit_instance option defaults to that unit. Coverage
data is collected separately for each instance of the unit type.
You can use using also per_unit_instance=sys to override a previous
setting of per_unit_instance.
Notes

radix=DEC|HEX|BIN

If you use per_unit_instance and no_collect for the same group, no


instances are created because no coverage data is collected. No
warning message is issued.
An Early Adopter feature is available that lets you assign logical names
to the cover group instances. See Using Logical Instance Names in
per_unit_instance Coverage in Specman Early Adopter Features.

Buckets for items of type int or uint are given the item value ranges as
names.This option specifies which radix the bucket names are displayed
in.
The global print radix option does not affect the bucket name radix.
Legal values are DEC (decimal), HEX (hexadecimal), and BIN (binary).
The value must be in upper case letters.
If the radix is not used, int or uint bucket names are displayed in decimal.
The names for per_instance subgroups must always be expressed in DEC
(decimal), regardless of the radix that you set. For more information, see
Sub-Group Names and the Item Radix in Managing Coverage for e
Testbenches.

text=string

A text description for this coverage group.


This can only be a quoted string, not a variable or expression. The text is
shown at the beginning of the information for the group in the coverage
report (displayed using the show cover command). In the Show Coverage
GUI, the text is shown for each item.

Specman e Language Reference


1999-2015

738

Product Version 15.1


All Rights Reserved.

Table 16-1

Coverage Group Options, continued

Option

Description

weight=uint

This option specifies the grading weight of the current group relative to
other groups. It is a nonnegative integer with a default of 1.

when=bool-exp

The coverage group is sampled only when bool-exp is TRUE. The


bool-exp is evaluated in the context of the parent struct.

Description
Defines a coverage group. A coverage group is struct member that contains a list of data items for which
data is collected over time.
Coverage defined in a struct is inherited by all like children of the stuct and can be extended in any of
the like children. Items that are added to the coverage group in a like child are only sampled when the
sampling event is emitted in the like child.
Like methods, coverage groups cannot be replaced in like children or when variants of the parent struct,
but they can be either extended or overridden in like children or when variants. An extension or
overriding of a coverage group in a like child or when variant is called a layer of the coverage group.
When a like child has already been defined for a struct and a coverage group has been defined for a
particular event in that like child, you cannot define a new coverage group in the parent struct using the
same event.
per_unit_instance Coverage
The group per_unit_instance option lets you collect separate coverage information for each instance of
a unit. Group per-instance coverage is useful, for example, if the DUT has two instances of a CPU
module, and you want to collect coverage separately for those two instances. By mapping two instances
of an e unit to the CPU instances and using the group per_unit_instance option, you can collect
coverage data separately for each CPU instance.
For more information, see:

Extending per_unit_instance Coverage in Managing Coverage for e Testbenches.

Using Logical Instance Names in per_unit_instance Coverage in Specman Early Adopter Features

Turning Off Coverage Mode


If cover groups are defined in the e code, coverage mode is on by default. The cover configuration
mode parameter controls the coverage mode. In the following example, the cover configuration option is
used to set the mode to off. See configure cover in the Specman Command Reference for more
information.

Specman e Language Reference


1999-2015

739
.

Product Version 15.1


All Rights Reserved.

extend sys {
setup() is also {
set_config(cover, mode, off); //turns off coverage collection
};
};

Options for Coverage Groups that Contain Type Real Items


All coverage group options are supported when the coverage group contains items of type real including
the per_unit_instance option.

Example 1

The radix option, when specified on the group level, is ignored for real items.

A coverage group named inst_driven is defined in the example below. The sampling event
inst_driven is declared earlier in the same struct. The coverage group contains definitions of three
basic coverage items named opcode, op1, and op2.
type cpu_opcode: [ADD, SUB, OR, AND, JMP, LABEL];
type cpu_reg: [reg0, reg1, reg2, reg3];
struct instruction_s {
opcode: cpu_opcode;
op1: cpu_reg;
op2: byte;
event inst_driven;
cover inst_driven is {
item opcode;
item op1;
item op2;
};
};

Example 2
The following code shows the effect of the group per_unit_instance option. In this example, an
instance of the cover group inst_driven is created for each instance of the alu_u unit.
struct instruction_s {
opcode: cpu_opcode;
op1: cpu_reg;
op2: byte;
event inst_driven;
cover inst_driven using per_unit_instance=alu_u is {
item opcode;
item op1;
item op2;
Specman e Language Reference
1999-2015

740

Product Version 15.1


All Rights Reserved.

};
unit alu_u {
inst_list: list of instruction_s;
};
extend sys {
alu0: alu_u is instance;
alu1: alu_u is instance;
};

Example 3
The code below contains examples of some of the coverage group options:

no_collect option: For the data_change group, do not save coverage data, but provide data for
show event.
text option: The text Main state machine appears at the beginning of the data for the group in the
ASCII coverage report.
when option: Coverage is collected for st when the state_change event occurs and
init_complete is TRUE.
global option: The reset_event is expected to occur only once. If it occurs more than once, a DUT
error is issued.
type cpu_opcode: [ADD, SUB, OR, AND, JMP, LABEL];
type cpu_reg: [reg0, reg1, reg2, reg3];
struct inst {
cache: c_mem;
opcode: cpu_opcode;
event info;
event data_change;
cover data_change using no_collect is {
item data: uint(bits:16) = cache.data;
};
cover info is {
item opcode;
};
};
type memory_mode: [full, partial];
type cpu_state: [START, FETCH1, FETCH2, EXEC];
struct cpu {
memory: memory_mode;
init_complete: bool;
event state_change;
event reset_event;
cover state_change using text = "Main state-machine",
when = (init_complete == TRUE) is {
item st: cpu_state = 'top.cpu.main_cur_state';
};

Specman e Language Reference


1999-2015

741
.

Product Version 15.1


All Rights Reserved.

cover reset_event using global is {


item memory;
};
};

Example 4
The code below shows the radix coverage group option:

For the len item, the bucket names are: 0x0, 0x1, ... 0x7 (using the HEX radix specified for the
group).
For the data item, the bucket names are: [0x0..0x03], [0x04..0x07], ... [0xfc..0xff] (using the HEX
radix specified for the item).
For the mask item, the bucket names are 0b00, 0b01, 0b10, and 0b11 (since the radix = BIN option
is used for this item to override the groups HEX radix.)
cover done using radix = HEX is {
item len: uint (bits: 3) = sys.len;
item data: byte = data using
ranges = {range([0..0xff], "", 4)},
radix = HEX;
item mask: uint (bits: 2) = sys.mask using radix = BIN;
};

Example 5
The code below shows the weight coverage group option.
The done coverage group is assigned a weight of 3. If there are 10 other coverage groups that all have
default weights of 1, the done group contributes (3/13)*grading(done) to the all grade.
cover done using weight = 3 is {
item len: uint (bits: 3) = sys.len;
item data: byte = data;
item mask;
};

Example 6
The code below shows how to use the empty coverage group keyword.
<'
struct inst {
cover done is empty;
};
extend inst {
data: byte;
Specman e Language Reference
1999-2015

742

Product Version 15.1


All Rights Reserved.

mask: uint(bits:2);
cover done is also {
item len: uint (bits: 3) = sys.len;
item data;
item mask;
};
};
'>

Example 7
The code below shows how to define coverage items in a when subtype, by extending a coverage group
defined previously. Two items named data and mask are added to the done coverage group in the
coverage group extension.
<'
struct inst {
mask: uint(bits:2);
data: byte;
size: [WIDE, REG];
event done;
cover done is {
item len: uint (bits: 3) = sys.len;
};
};
extend inst {
when WIDE inst {
cover done is also {
item data;
item mask;
};
};
};
'>

Example 8
The code below shows how to define coverage items in a like child, by extending a coverage group
defined previously. The result is one coverage group, done, with two items, len and mask.
<'
struct inst {
mask: byte;
size: [WIDE, REG];
event done;
cover done is {
Specman e Language Reference
1999-2015

743
.

Product Version 15.1


All Rights Reserved.

item len: uint (bits: 3) = sys.len;


};
};
struct inst_child like inst {
cover done is also {
item mask;
};
};
'>

The code below shows how to override a coverage group in a like child, by extending a coverage group
defined previously. The result is two coverage groups, inst.done, with one item, len, and
inst_child.done, with one item, mask.
Coverage items in the parent struct cannot be accessed by the coverage group in the overriding struct
(that is, the like child).
<'
struct inst {
mask: uint(bits:2);
size: [WIDE, REG];
event done;
cover done is {
item len: uint (bits: 3) = sys.len;
};
};
struct inst_child like inst {
cover done is {
item mask;
};
};
'>

Example 9
The code below shows how the instance_no_collect group option can be used to determine the unit
instances for which this cover group is relevant.
unit u{
event ev;
do_not_emit_ev: bool;
cover ev using per_unit_instance, instance_no_collect =
inst.do_not_emit_ev is{
item x: bit =1;
item y: bit = 0;
Specman e Language Reference
1999-2015

744

Product Version 15.1


All Rights Reserved.

};
};
//
extend u {
do_not_collect_cov: bool;
cover ev using also instance_no_collect = (prev or
inst.do_not_collect_cov);
}

In this case, only unit instances for which the do_not_emit_ev and do_not_collect_cov fields are
set to FALSE, will have an instance of this cover group.

See Also

Defining Basic Coverage Items on page 745

Defining Cross Coverage Items on page 769

Defining Transition Coverage Items on page 785

Extending Coverage Groups on page 798

Defining Coverage Models in Managing Coverage for e Testbenches

Chapter 12 Events

Chapter 3 Structs, Fields, and Subtypes

show cover in the Specman Command Reference

configure cover in the Specman Command Reference

16.2 Defining Basic Coverage Items


This section describes how to define basic coverage items in the following sections:

item on page 746

See Also

Defining Coverage Models in Managing Coverage for e Testbenches

Defining Coverage Groups on page 735

Defining Cross Coverage Items on page 769

Defining Transition Coverage Items on page 785

Extending Coverage Items on page 805

Defining Structs on page 216

Specman e Language Reference


1999-2015

745
.

Product Version 15.1


All Rights Reserved.

show cover in the Specman Command Reference

configure cover in the Specman Command Reference

16.2.1

item

Purpose
Define a coverage item

Category
Coverage group item

Syntax
item item-name[:type=exp] [using coverage-item-option, ...]
Syntax Example
cover inst_driven is {
item op1;
item op2;
item op2_big: bool = (op2 >= 64);
item hdl_sig: int = 'top.sig_1';
};

Parameters
item-name

The name of the coverage item.


If you do not specify the optional type=exp, the name is assumed to be the name
of a field in the enclosing struct or unit. The field must be a scalar type not larger
than 32 bits or a string type. The value of the cover item is the value of the field
when the cover group event occurs.
Note Items of type string and large, unconstrained integers are ungradable
because it is not reasonable to try to cover all possible values. ungradable items in
the coverage model can cause scalability and usability problems. See Dealing with
Ungradable Items, Ignored Items, and Default Buckets in Managing Coverage for
e Testbenches for more information.

Specman e Language Reference


1999-2015

746

Product Version 15.1


All Rights Reserved.

type=exp

Used to declare a new item (not an existing field), this expression is evaluated
when the cover group event occurs, and its value becomes the value of the item.
For example, the following code defines a cover item whose value is the value of
the first item in the b_list field:
item b0: byte = b_list[0];

The type expression must evaluate to a scalar type not larger than 32 bits or a
string type.
coverage-itemoption
Table 16-2

Coverage item options are listed in Table 16-2. The options can appear in any
order after the using keyword.

Coverage Item Options

Option

Description

at_least=num

The minimum number of samples for each bucket of the item. Anything
less than num is considered a hole.
The value must be a non-negative integer. The default is 1.
This option cannot be used with string items or for unconstrained integers
(items that have no specified ranges).

first_high_bit

Collect power-of-two coverage. The sampled value is the location of the


most significant bit, which is set to 1. When you specify this option,
Specman creates the ranges with the following names for numeric items
of n bits:

0: for samples where the items value is 0.


Bit k for each value of k between 0 and n -1: for samples where bit k
is set to 1, and all bits located to the left of k are set to 0.

If you do not specify the text option, Specman sets the text string to
Most Significant 1 Bit Location Collection.
Note Specman issues an error if you use this option with the ranges or
num_of_buckets options for the same item.

Specman e Language Reference


1999-2015

747
.

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

ignore=item-bool-ex

Define values that are to be completely ignored. They do not appear in


the statistics at all. The expression is a Boolean expression that can
contain a coverage item name and constants.
The Boolean expression is evaluated in a global context, not in instances
of the struct. In other words, the expression must be valid at all times,
even before generation. Therefore, you can only use constants and the
item itself in the expression. In a cross, that means any of the
participating items. In a transition, that means the item or prev_item.
For example, if i is a coverage item and j is a reference to a struct
field, the expression i > 5 is a valid expression, but i > me.j is not
legal.
Using ignore has two effects:
1.

If the ignore expression is TRUE when the data is sampled, the


sampled value is ignored (that is, not added to the bucket count).

2.

When you view the results with show cover or with the coverage
GUI, Specman queries the ignore expression for each hole in the
coverage results. If the ignore expression is TRUE:

The bucket is hidden, rather than identified as a hole.


Coverage grades are computed without taking into account the
bucket contents.
If you want to achieve the first effect (ignore specific samples), but you
do not want to hide buckets containing holes and you want the grade to
reflect all generated values, use the when option instead. This description
also appears in the cross and transition item descriptions.

See Analyzing the Effects of the ignore and illegal Options in Managing
Coverage for e Testbenches for more information about the effects of the
ignore option.
Note You can use the show cover -space command to reports the
number of legal buckets defined for the item versus the number of buckets
that would be defined if the illegal and ignore coverage options did not
apply.

Specman e Language Reference


1999-2015

748

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

illegal=item-bool-exp

Define values that are illegal. An illegal value causes a DUT error. If the
check_illegal_immediately coverage configuration option is FALSE,
the DUT error occurs during the check_test phase of the test. If that
configuration option is TRUE, the DUT error occurs immediately (on the
fly). Note that checking illegal values immediately has a significant
negative impact on Specman performance.
See illegal on page 765 for an example of how to set the error effect of
this check to WARNING instead of ERROR.
The Boolean expression is evaluated in a global context, not in instances
of the struct. In other words, the expression must be valid at all times,
even before generation. Therefore, you can only use constants and the
item itself in the expression. In a cross, that means any of the
participating items. In a transition, that means the item or prev_item.
For example, if i is a coverage item and j is a reference to a struct
field, the expression i > 5 is a valid expression, but i > me.j is not
legal.
When you view result with show cover or the coverage GUI, Specman
queries the illegal expression. If the illegal expression is TRUE, coverage
grades are computed without taking into account the bucket contents.
If, on the other hand, you want the coverage grades to reflect all bucket
contents, use the when option instead to specify the circumstances under
which a given value is counted. This description also appears in the cross
and transition item descriptions (last sentence in third para is different in
each description).
See Analyzing the Effects of the ignore and illegal Options in Managing
Coverage for e Testbenches for more information about the effects of the
illegal option.
Note You can use the show cover -space command to report the
number of legal buckets defined for the item versus the number of buckets
that would be defined if the illegal and ignore coverage options did not
apply.

Specman e Language Reference


1999-2015

749
.

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

instance_ignore=expr

Define a context-dependent ignore expression on items in


per_unit_instance groups. This option lets you set ignore expressions
for an instance, depending on the scope.
Like the boolean expression for the ignore option for basic items, the
expr argument for instance_ignore can contain the item itself and global
values. However, the instance_ignore expression also includes an inst
field. In the context of an explicit per-unit instance or for cover groups
defined under a struct or unit, the inst field contains a pointer to the unit
defined by the per_unit_instance option. In the case of an implicit
per-unit instance collection of cover groups defined under units, the inst
field refers to the enclosing unit.
The fields used in the expression should remain constant throughout the
run. Otherwise, false holes can occur in the coverage results.
Furthermore, when an instance_ignore expression is defined for an item,
its unit type must be known and cannot change after the definition. As a
result:

Specman e Language Reference


1999-2015

For a cover group defined inside a struct, an instance_ignore


expression cannot be defined for one of its items before the
per_unit_instance is defined for the cover group.
After an instance_ignore expression is defined for a cover group item,
the per_unit_instance type cannot be changed.

750

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

instance_illegal=expr

Define a context-dependent illegal expression on items in


per_unit_instance groups. This option lets you set illegal expressions
for an instance, depending on the scope.
Like the boolean expression for the illegal option for basic items, the expr
argument for instance_illegal can contain the item itself and global
values. However, the instance_illegal expression also includes an inst
field. In the context of an explicit per-unit instance or for cover groups
defined under a struct or unit, the inst field contains a pointer to the unit
defined by the per_unit_instance option. In the case of an implicit
per-unit instance collection of cover groups defined under units, the inst
field refers to the enclosing unit.
The fields used in the expression should remain constant throughout the
run. Otherwise, false holes can occur in the coverage results.
Furthermore, when an instance_illegal expression is defined for an item,
its unit type must be known and cannot change after the definition. As a
result:

For a cover group defined inside a struct, an instance_illegal


expression cannot be defined for one of its items before the
per_unit_instance is defined for the cover group.
After an instance_illegal expression is defined for a cover group item,
the per_unit_instance type cannot be changed.

Specman e Language Reference


1999-2015

751
.

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

instance_no_collect=ex
pr

Define a context-dependent no_collect expression on items in


per_unit_instance groups. This option lets you set no_collect
expressions for an instance, depending on the scope.
The expr argument for instance_no_collect can include an inst field. In
the context of an explicit per-unit instance or for cover groups defined
under a struct or unit, the inst field contains a pointer to the unit defined
by the per_unit_instance option. In the case of an implicit per-unit
instance collection of cover groups defined under units, the inst field
refers to the enclosing unit.
When an instance_no_collect expression is defined for an item, its unit
type must be known and cannot change after the definition. As a result:

no_collect=bool

For a cover group defined inside a struct, an instance_no_collect


expression cannot be defined for one of its items before the
per_unit_instance is defined for the cover group.
After an instance_no_collect expression is defined for a cover group
item, the per_unit_instance type cannot be changed.

When no_collect[=TRUE], this coverage item is not displayed in


coverage reports and is not saved in the coverage files.
The primary use of this option is to specify cover items whose individual
coverage grades are of no interest, but whose cross coverage grade is
desired. For example:
item x using no_collect;
// Not interested in x itself
item y using no_collect;
// Not interested in y itself
cross x, y;
// Interested in the cross of x an y

This option also enables tracing of coverage information and enables


event viewing with trace event, without saving the coverage
information. Setting this option to TRUE overrides the global config
cover mode setting of on or on_interactive.
You can use using also no_collect=FALSE to override a previous setting
of no_collect[=TRUE].

Specman e Language Reference


1999-2015

752

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

no_trace=bool

When no_trace[=TRUE], this item is not traced by the simulator. Use


this option to collect data for trace event.
You can use using also no_trace=FALSE to override a previous setting
of no_trace[=TRUE].

num_of_buckets=num

Specifies how many buckets are to be created for the coverage item. This
option overrides the max_int_buckets coverage configuration option for
this coverage item. It cannot be used for string items or items that have
ranges specified with the ranges coverage item option. It can be set to
any value, including greater than max_int_buckets.

per_instance=bool

When per_instance[=TRUE], coverage data is collected and graded for


all the other items in a separate sub-group for each bucket of this item.
This option can only be used for gradeable items.
You can use using also per_instance=FALSE to override a previous
setting of per_instance[=TRUE].
Note If you use per_instance and no_collect for the same item, the
WARN_PER_INST_TRACE_ONLY warning message is issued. This
indicates that no instances are created because no coverage data is
collected. To fix this problem, delete the no_collect option for this item or
use using also no_collect=FALSE to override the previous setting of
no_collect.

Specman e Language Reference


1999-2015

753
.

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

radix=DEC|HEX|BIN

For items of type int or uint, specifies the radix used in coverage reports
for implicit buckets. If the ranges option is not used to create explicit
buckets for an item, a bucket is created for every value of the item that
occurs in the test. Each different value sampled gets its own bucket, with
the value as the name of the bucket. These are called implicit buckets.
Legal values are DEC (decimal), HEX (hexadecimal), and BIN (binary).
The value must be in upper case letters. If the radix is not used, int or
uint bucket names are displayed in decimal.
The global print radix option does not affect the bucket name radix.
If no radix is specified for an item, but a radix is specified for the items
group, the groups radix applies to the item.
Note The names for per_instance subgroups must always be
expressed in DEC (decimal), regardless of the radix that you set. For more
information, see Referencing Item Instances in Managing Coverage for e
Testbenches.

Specman e Language Reference


1999-2015

754

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

ranges =
{range(parameters);}

Create buckets for this items values or ranges of values. This option
cannot be used for string items.
The range() has up to four parameters. The parameters specify how the
values are separated into buckets. The first parameter, range, is required.
The other three are optional. The syntax for range options is:
range(range: range, name: string, every-count: int, at_least-num: int)
The parameters are:

range: The range for the bucket. The range must be a literal range
such as [1..5], of the proper type. Even a single value must be
specified in brackets (for example [7]). If you specify ranges that
overlap, values in the overlapping region go into the first of the
overlapping buckets. The specified range for a bucket is the bucket
name. That is, the buckets above are named [1..5] and [7].
name: A name for the bucket. If you use the name parameter, you
cannot use an every-count value. Instead, you must enter UNDEF for
the every-count parameter.
item p using ranges =
{range([0..7], "low ranges", UNDEF, 1);};

every-count: The size of the buckets to create within the range. If you
use the every-count parameter, you cannot use a name. Instead, you
must enter an empty string () as a placeholder for the name
parameter. For example:
item p using ranges =
{range([0..7], "", 1, 1);};

at-least-num: The minimum number of samples required for a bucket.


If the item is sampled fewer times than this, a hole is marked. This
parameter overrides the global at_least option and the per-item
at_least option. The value of at-least-num can be set to zero, meaning
do not show holes for this range.

Note If a value for an item falls outside all of the buckets for the item,
that value does not count toward the items grade.
To define a range for an item of type real, see Specifying Real Item
Coverage Ranges in Managing Coverage for e Testbenches.

Specman e Language Reference


1999-2015

755
.

Product Version 15.1


All Rights Reserved.

Table 16-2

Coverage Item Options, continued

Option

Description

text=string

A text description for this coverage item. This can only be a quoted
string, not a variable or expression. In the ASCII coverage report the text
is shown along with the item name at the top of the coverage information
for the item. In the Show Coverage GUI, the text is shown for each item.

weight=uint

Specifies the weight of the current item relative to other items in the same
coverage group. It is a non-negative integer with a default of 1.

when=bool-exp

The item is sampled only when bool-exp is TRUE. The bool-exp is


evaluated in the context of the parent struct.
The sampling is done at run time.

Description
Defines a basic coverage item with an optional type and expression. The item can be an existing field
name, or a new name. If you use a new name for a coverage item, you must specify the items type and
the expression that defines its value.
Using the per_instance item option lets you collect coverage information grouped by a particular value
or range of values for a specified cover item. Specifying an item as a per-instance item creates multiple
instances of a cover item one instance for each of the items buckets. Specman then crosses each item
instance with each of the other items in that cover group, presenting the results as separate sub-groups
with separate coverage grades. Item per-instance coverage is useful, for example, if the DUT handles
several kinds of packets and you want to collect coverage separately for each packet subtype. For more
information, see Collecting Separate Coverage Data for Item Instances in Managing Coverage for e
Testbenches.
Items that have no limited range of values or whose ranges are wider than the max_int_buckets
configuration option are called ungradable items. For example, string items, which have no ranges, and
unconstrained 32-bit integer items, which have very large ranges, are ungradable. This is because there
are so many possible values for those types of items that it is not reasonable to try to cover all their
values. Because ungradable items in the coverage model can cause scalability and usability problems,
such as Specman running out of memory and unexpected grading results, there are several options,
including ranges and num_of_buckets, that make integer items gradeable. There is no way to make
string items gradeable. See Dealing with Ungradable Items, Ignored Items, and Default Buckets in
Managing Coverage for e Testbenches for more information.
Additional item options specify how coverage data is collected and reported for the item.

Specman e Language Reference


1999-2015

756

Product Version 15.1


All Rights Reserved.

See Also

Defining Coverage for Real Numbers in Managing Coverage for e Testbenches

Example 1

type=exp

The following example uses type=exp to define coverage for a list element. In the b0 item definition, the
type is byte and exp is b_list[0]. This collects coverage data for the value of the first byte in b_list.
This example also shows a predefined list method, b_list.size(), used in the item definition expression.
struct mem {
b_list: list of byte;
keep b_list.size() in [2..16];
event mem_ch;
cover mem_ch is {
item b0: byte = b_list[0];
item b_list_size: uint (bits: 4) = b_list.size();
};
};

Example 2

type=exp

The following example uses the type=exp parameter in the mem_mode item definition to define
coverage for a struct field which is instantiated through a hierarchy of struct instances. The type is
memory_type. The exp is the hierarchical path sys.config.mem_type.
struct mem {
event mem_ch;
cover mem_ch is {
item mem_mode: memory_mode = sys.config.mem_mode;
};
};
struct config {
mem_mode: memory_mode;
keep mem_mode == 'top.mem_mode';
};

Example 3

type=exp and when

The following example demonstrates a way to cover different combinations of values for particular bits
of an item. It uses type=exp and the when coverage item option to collect coverage for bit 14 = 0, bit 15
= 0 versus bit 14 = 0, bit 15 = 1 of a 16-bit unit item named opcode.
struct inst {
Specman e Language Reference
1999-2015

757
.

Product Version 15.1


All Rights Reserved.

opcode: uint (bits: 16);


len: int [1..3];
event fetch;
cover fetch is {
item opcode using radix = BIN;
item opcode0: uint (bits: 2) = opcode
using when = (opcode[15:14] == 2'b00);
item opcode1: uint (bits: 2) = opcode
using when = (opcode[15:14] == 2'b01);
item len;
};
run() is also {
emit fetch;
};
};

Example 4

ranges and at_least

In the following example, coverage data is collected for a field generated on the fly. The field is
addr_tmp, which has been added just to serve as a coverage item. The addr_tmp values replace the addr
field values in a previously generated list of packets structs.
For each addr_tmp value generated in the for loop, the cov_addr event is emitted to take a coverage
sample of the addr_tmp value. The new addr_tmp value is then placed in the addr field in the current
packet instance.
The ranges option is used in the addr_tmp coverage item definition to create four buckets, for values
from 0 to 63, 64 to 127, 128 to 191, and 192 to 255. The at_least option is also used, to specify that any
bucket that does not get at least three values is a hole.
struct packet {
%addr: byte;
%len: uint (bytes: 2);
%data[len]: list of byte;
};
struct pkts {
packets: list of packet;
keep packets.size() == 12;
};
extend pkts {
addr_tmp: byte;
add_addr()@sys.clk is {
for i from 0 to packets.size() - 1 do {
gen addr_tmp;
emit cov_addr;
packets[i].addr = addr_tmp;
Specman e Language Reference
1999-2015

758

Product Version 15.1


All Rights Reserved.

wait cycle;
};
stop_run();
};
event cov_addr;
cover cov_addr is {
item addr_tmp using ranges = {range([0..255], "", 64)},
at_least = 3;
};
run() is also {
start add_addr();
};
};

Example 5

per_instance

The following example specifies that the p_type item is a per_instance item. For each of the buckets of
the p_type item, rx, tx, and ctrl, coverage data is collected and grades are calculated for the len item. The
coverage report follows the sample code.
type packet_type : [rx, tx, ctrl];
struct packet {
p_type: packet_type;
len: uint[0..7];
event pkt_started;
cover pkt_started is {
item p_type using per_instance;
item len;
};
};

Report
The following is the coverage report displayed by the show cover command for Example 5 on
page 759.
Specman test3> show cover packet.pkt_started(p_type==rx)
Specman Coverage report
=======================
Command:
show cover -kind = full packet.pkt_started(p_type==rx).*
Grading_formula:
linear
At least multiplier: 1
Show mode:
both
Specman e Language Reference
1999-2015

759
.

Product Version 15.1


All Rights Reserved.

Number of tests:
Note:

1
%t is a percent from total, %p is a percent from parent

Cover group: packet.pkt_started(p_type==rx)


===========================================
Grade: 0.50
** len **
Samples: 5

Weight: 1

Tests: 1

Grade: 0.50

Weight: 1

grade
goal
samples
tests
%t
len
-----------------------------------------------1.00
1
1
1
20
0
0.00
1
0
0
0
1
1.00
1
1
1
20
2
1.00
1
2
1
40
3
0.00
1
0
0
0
4
0.00
1
0
0
0
5
0.00
1
0
0
0
6
1.00
1
1
1
20
7

Example 6

ignore

The example below shows the ignore option used to ignore a particular instance, p_type==ctrl, of the
p_type item. The coverage report shows grades for the per_type, rx and tx sub-groups. The coverage
report, shown following the code, does not contain any data for the ctrl sub-group.
type packet_type : [rx, tx, ctrl];
struct packet {
p_type: packet_type;
%data: list of bit;
kee data.size() < 16;
event pkt_started;
cover pkt_started is {
item p_type using per_instance, ignore =(p_type==ctrl);
item len: int = pack(packing.low, me).size();
};
};

Output
The following is the coverage report displayed by the show cover instruction command for Example 6
on page 760.
Specman e Language Reference
1999-2015

760

Product Version 15.1


All Rights Reserved.

Specman test3> show cover packet.pkt_started(*)

Specman Coverage report


=======================
Command:
show cover -kind = full packet.pkt_started.*
Grading_formula:
linear
At least multiplier: 1
Show mode:
both
Number of tests:
1
Note:
%t is a percent from total, %p is a percent from parent

Cover group: packet.pkt_started


===============================
Grade: 1.00 Weight: 1
** p_type **
Samples: 16 Tests: 1

Grade: 1.00

Weight: 1

grade
goal
samples
tests
%t
p_type
-----------------------------------------------1.00
1
10
1
63
rx
1.00
1
6
1
38
tx

** len **
Samples: 20 Tests: 1

Grade: 1.00 Weight: 1

grade
goal
samples
tests
%t
len
-----------------------------------------------1.00
1
1
1
5
0
0.00
1
3
1
15
1
0.00
1
1
1
5
2
0.00
1
3
1
15
3
0.00
1
5
1
25
4
0.00
1
1
1
5
5
0.00
1
2
1
10
6
0.00
1
4
1
20
7

Cover group: packet.pkt_started(p_type==rx)


===========================================

Specman e Language Reference


1999-2015

761
.

Product Version 15.1


All Rights Reserved.

Grade: 0.12
** len **
Samples: 5

Weight: 1

Tests: 1

Grade: 0.12

Weight: 1

grade
goal
samples
tests
%t
len
-----------------------------------------------0.00
1
0
0
0
0
1.00
1
2
1
20
1
1.00
1
1
1
10
2
1.00
1
1
1
10
3
1.00
1
2
1
20
4
1.00
1
1
1
10
5
1.00
1
1
1
10
6
1.00
1
2
1
20
7

Cover group: packet.pkt_started(p_type==tx)


===========================================
Grade: 0.12

Weight: 1

** len **
Samples: 11

Tests: 1

Grade: 0.12

Weight: 1

grade
goal
samples
tests
%t
len
-----------------------------------------------1.00
1
1
1
17
0
1.00
1
1
1
17
1
0.00
1
0
0
0
2
1.00
1
1
1
17
3
1.00
1
1
1
17
4
0.00
1
0
0
0
5
0.00
1
0
0
0
6
1.00
1
2
1
33
7

Example 7

per_instance and illegal

The example below shows the illegal option used with a per_instance item.
define MAX_PORTS 4;
type port_id_kind: [PORT_0, PORT_1, PORT_2, PORT_3];
struct port {
port_id: port_id_kind;
status: uint(bits:2);

Specman e Language Reference


1999-2015

762

Product Version 15.1


All Rights Reserved.

event pkt_ended;
cover pkt_ended is {
item port_id using per_instance,
illegal = (port_id.as_a(int) < MAX_PORTS);
item status;
};
};

Example 8

no_collect

struct sm {
cpu: top_cpu;
event cs;
cover cs is {
item cb: bit = cpu.carry using no_collect;
};
};

Coverage information is not collected for item cb, but the item can be used in cross coverage, and
Verilog tracing can be done on it and it is displayed by the trace event command.

Example 9

text

type state_name: [S1, S2];


struct sm {
st: state_name;
event state_change;
cover state_change is {
item st using text = "The CPU state";
};
};

The text is displayed with the data for item st in the coverage report.

Example 10

ranges

struct pcc {
pc_on_page_boundary: uint (bits: 15);
pc: uint (bits: 15);
stack_change: byte;
event pclock;
cover pclock is {
item pc_on_page_boundary using
ranges = {
range([0], "0"); range([4k], "4k");
range([8k], "8k"); range([12k], "12k");
range([16k], "16k"); range([20k], "20k");
Specman e Language Reference
1999-2015

763
.

Product Version 15.1


All Rights Reserved.

range([24k], "24k"); range([28k], "28k");


range([0..32k-1], "non-boundary");
};
item pc using radix = HEX,
ranges = {
range([0..4k-1], "page_0", UNDEF, 4);
range([4k..32k-1], "", 8k, 2);
};
item stack_change using
ranges = { range( [0..32], "", 1); };
};
};

The range specifications in this example create the following buckets:

Item pc_on_page_boundary:
Bucket names: 0, 4k, 8k, 12k, 16k, 20k, 24k, 28k
Each of these buckets will hold the given value.
Bucket name: non-boundary:
This bucket will hold all values from 0 to 32k-1 that are not put into one of the buckets above.

Item pc:
Bucket name: page_0
This bucket will hold values from 0 to 4095, and must contain at least four samples (because
at_least_num is 4).
Bucket names: 0x1000..ex2fff, 0x3000..0x4fff, 0x5000..0x6fff, 0x7000..0x7cff
Each of these buckets will hold values in the given range and must contain at least two samples
(because every_count is 8k, and at_least_num is 2).

Item stack_change:
Bucket names: 0, 1, 2, ..., 32
Each of these buckets will hold the given value (because every_count is 1).

Example 11

num_of_buckets

struct packet {
my_size: int (bits: 16);
event xfer;
cover xfer is {
item my_size using num_of_buckets = 16;
};
};
Specman e Language Reference
1999-2015

764

Product Version 15.1


All Rights Reserved.

The my_size coverage item is divided into 16 buckets, regardless of the value of max_int_buckets.

Example 12

ignore

struct packet {
len: uint (bytes: 2);
event xfer;
cover xfer is {
item len using ignore = (len > 32k);
};
};

Any len value greater than 32,768 is ignored.

Example 13

illegal

struct packet {
packet_len: uint (bits: 12);
event rcv_clk;
cover rcv_clk is {
item len: uint (bits: 12) = packet_len using
ranges = {
range( [16..255], "small");
range( [256..3k-1], "medium");
range( [3k..4k-1], "big");
},
illegal = (len < 16 or len > 4000);
};
};

Any len value less than 16 or greater than 4,096 is illegal. If an illegal len value occurs, a DUT error
is issued during the check_test phase of the test. The ranges option creates buckets for values from 16
to 4,096.
You can use the set check command to set the effect of the DUT error to WARNING, to allow continued
execution of the test even if illegal values occur. For example:
set check "Illegal value for cover item..." WARNING

Example 14

instance_ignore

<'
unit u{
max_val: uint(bits:3);
x: uint(bits:3);
event ev;
cover ev using per_unit_instance is{
item x using ignore = (x==0), instance_ignore=(x > inst.max_val);
Specman e Language Reference
1999-2015

765
.

Product Version 15.1


All Rights Reserved.

};
run() is {
for i from 1 to 5{
gen x keeping {it >= 1 and it <= max_val};
emit ev;
};
};
};
extend sys{
u1: u is instance;
keep u1.max_val == 6;
u2: u is instance;
keep u2.max_val == 4;
};
'>

In this example, Specman creates 7 bins for the 7 possible values of x. However, instance u1 ignores the
value 7, and instance u2 ignores the values 5 through 7.

When you view the per-type coverage for the test run, you see the results for all bins, including bin 7.

When you view the results for u1, you see only bins 1 through 6.

When you view the results for u2, you see only bins 1 through 4.

Example 15

instance_illegal

unit u{
max_x_val: uint(bits:3);
max_y_val: uint(bits:3);
allow_x_eq_y: bool;
x: uint(bits:3);
keep x <= max_x_val;
y: uint(bits:3);
keep y <= max_y_val;
when FALSE'allow_x_eq_y{
keep x != y;
};
event ev;
cover ev using per_unit_instance is{
item x using instance_illegal=(x > inst.max_x_val);
item y using instance_illegal=(y > inst.max_y_val);
Specman e Language Reference
1999-2015

766

Product Version 15.1


All Rights Reserved.

cross x,y using instance_illegal=(not inst.allow_x_eq_y) and (x ==


y);
};
};
extend sys{
u1: u is instance;
keep u1.allow_x_eq_y;
u2: u is instance;
keep not u2.allow_x_eq_y;
};

Example 16

instance_no_collect

unit u{
event ev;
remove_y: bool;
cover ev using per_unit_instance is{
item x: bit =1;
item y: bit = 0 using instance_no_collect = inst.remove_y;
};
run() is also{
emit ev;
};
};
extend sys{
u1: u is instance;
keep u1.remove_y;
u2: u is instance;
keep not u2.remove_y;
};

Example 17

radix

cover done is {
item len: uint (bits: 3) = packet_len;
item data: byte = data using
ranges = {range([0..0xff], "", 16)};
item mask: uint (bits: 2) = mask using radix = BIN;
};

For the len item, the bucket names are: 0, 1, ... 7 (using the default decimal radix).
For the data item, the bucket names are: [0..15], [16..31], ... [240..255] (using the default decimal
radix).
For the mask item, the bucket names are 0b00, 0b01, 0b10, and 0b11 (using the radix = BIN option
specified for this item).
Specman e Language Reference
1999-2015

767
.

Product Version 15.1


All Rights Reserved.

Example 18

weight

cover done is {
item len: uint (bits: 3) = packet_len;
item data: byte = data;
item mask using weight = 2;
};

The mask item is assigned a weight of 2. Since there are two other items, len and data, with
default weights of 1, the mask item contributes (2/4)*grading(done) to the grade for the group.

Example 19

no_trace

struct packet {
event done;
mask: uint (bits: 2);
packet_data: byte;
cover done is {
item data: byte = packet_data;
item mask using no_trace;
};
};

The done event is marked for tracing, but the mask item in the done coverage group is marked
no_trace, so it is not traced in the simulator and is not displayed by trace event.

Example 20

first_high_bit and no_collect

extend sys{
alu is instance;
xu1: uint(bits:3);
xu2: uint(bits:3);
event unsigned_mult;
on unsigned_mult{
var res: uint(bits:6) = alu.unsigned_mult(xu1, xu2);
assert (res == xu1 * xu2);
};
cover unsigned_mult is{
item xu1 using first_high_bit, no_collect;
item xu2 using first_high_bit, no_collect;
cross xu1, xu2;
};
};
Specman e Language Reference
1999-2015

768

Product Version 15.1


All Rights Reserved.

Report example for this code:


Cover group: sys.unsigned_mult
==============================
Grade: 0.81

Weight: 1

** cross__xu1__xu2 **
Samples: 50 Tests: 1

Grade: 0.81

Weight: 1

grade
goal
samples tests
%p/%t xu1/xu2
-----------------------------------------------------0.50
5
1
10/10 0
1.00
1
2
1
40/4
0/0
0.00
1
0
0
0/0
0/Bit0
0.00
1
0
0
0/0
0/Bit1
1.00
1
3
1
60/6
0/Bit2
0.75
4
1
8/8
Bit0
1.00
1
1
1
25/2
Bit0/0
1.00
1
1
1
25/2
Bit0/Bit0
1.00
1
2
1
50/4
Bit0/Bit1
0.00
1
0
0
0/0
Bit0/Bit2
1.00
12
1
24/24 Bit1
1.00
1
1
1
8/2
Bit1/0
1.00
1
1
1
8/2
Bit1/Bit0
1.00
1
1
1
8/2
Bit1/Bit1
1.00
1
9
1
75/18 Bit1/Bit2
1.00
29
1
58/58 Bit2
1.00
1
5
1
17/10 Bit2/0
1.00
1
2
1
7/4
Bit2/Bit0
1.00
1
7
1
24/14 Bit2/Bit1
1.00
1
15
1
52/30 Bit2/Bit2When

16.3 Defining Cross Coverage Items


Cross items are combinations of items from the same coverage group. The cross coverage construct is
used to define cross items. The following sections describe how to define cross coverage items:

cross on page 770

See Also

Defining Coverage Groups on page 735

Defining Basic Coverage Items on page 745

Specman e Language Reference


1999-2015

769
.

Product Version 15.1


All Rights Reserved.

Extending Coverage Items on page 805

show cover in the Specman Command Reference

16.3.1

cross

Purpose
Define a cross coverage item

Category
Coverage group item

Syntax
cross item-name-1, item-name-2, ... [using coverage-item-option, ...]
Syntax Example
cover inst_driven is {
item opcode;
item op1;
cross opcode, op1;
};

Parameters
item-name-1,
item-name-2, ...

Each item name must be one of the following.

coverage-itemoption

The name of an item defined previously in the current coverage group


The name of a transition item defined previously in the current coverage group
The name of a cross item defined previously in the current coverage group

An option for the cross item. The options are listed in Table 16-3.

Specman e Language Reference


1999-2015

770

Product Version 15.1


All Rights Reserved.

Table 16-3

Cross Coverage Item Options

Option

Description

at_least=num

A non-negative integer specifying the minimum number of samples for


each bucket of the item. Anything less than num is considered a hole. The
default is 1.
This option cannot be used with string items or for unconstrained integers
(items that have no specified ranges).

Specman e Language Reference


1999-2015

771
.

Product Version 15.1


All Rights Reserved.

Table 16-3

Cross Coverage Item Options, continued

Option

Description

ignore=item-bool-exp

Define values that are to be completely ignored. They do not appear in the
statistics at all. The expression is a Boolean expression that can contain a
coverage item name and constants.
The Boolean expression is evaluated in a global context, not in instances of
the struct. In other words, the expression must be valid at all times, even
before generation. Therefore, you can only use constants and the item itself
in the expression. In a cross, that means any of the participating items. In a
transition, that means the item or prev_item.
For example, if i is a coverage item and j is a reference to a struct field,
the expression i > 5 is a valid expression, but i > me.j is not legal.
Using ignore has two effects:
1.

If the ignore expression is TRUE when the data is sampled, the sampled
value is ignored (that is, not added to the bucket count).

2.

When you view the results with show cover or with the coverage GUI,
Specman queries the ignore expression for each hole in the coverage
results. If the ignore expression is TRUE:

The bucket is hidden, rather than identified as a hole.


Coverage grades are computed without taking into account the
bucket contents.
If you want to achieve the first effect (ignore specific samples), but you do
not want to hide buckets containing holes and you want the grade to reflect
all generated values, use the when option instead. This description also
appears in the basic and transition item descriptions.

See Analyzing the Effects of the ignore and illegal Options in Managing
Coverage for e Testbenches for more information about the effects of the
ignore option.
Note You can use the show cover -space command to reports the
number of legal buckets defined for the item versus the number of buckets
that would be defined if the illegal and ignore coverage options did not
apply.

Specman e Language Reference


1999-2015

772

Product Version 15.1


All Rights Reserved.

Table 16-3

Cross Coverage Item Options, continued

Option

Description

illegal=item-bool-exp

Define values that are illegal. An illegal value causes a DUT error. If the
check_illegal_immediately coverage configuration option is FALSE, the
DUT error occurs during the check_test phase of the test. If that
configuration option is TRUE, the DUT error occurs immediately (on the
fly). Note that checking illegal values immediately has a significant
negative impact on Specman performance.
See illegal on page 765 for an example of how to set the error effect of this
check to WARNING instead of ERROR.
The Boolean expression is evaluated in a global context, not in instances of
the struct. In other words, the expression must be valid at all times, even
before generation. Therefore, you can only use constants and the item itself
in the expression. In a cross, that means any of the participating items.
For example, if i is a coverage item and j is a reference to a struct field,
the expression i > 5 is a valid expression, but i > me.j is not legal.
When you view result with show cover or the coverage GUI, Specman
queries the illegal expression. If the illegal expression is TRUE, coverage
grades are computed without taking into account the bucket contents.
If, on the other hand, you want the coverage grades to reflect all bucket
contents, use the when option instead to specify the circumstances under
which a given value is counted. This description also appears in the cross
and transition item descriptions (last sentence in third para is different in
each description).
See Analyzing the Effects of the ignore and illegal Options in Managing
Coverage for e Testbenches for more information about the effects of the
illegal option.
Note You can use the show cover -space command to reports the
number of legal buckets defined for the item versus the number of buckets
that would be defined if the illegal and ignore coverage options did not
apply.

Specman e Language Reference


1999-2015

773
.

Product Version 15.1


All Rights Reserved.

Table 16-3

Cross Coverage Item Options, continued

Option

Description

instance_ignore=exp
r

Define a context-dependent ignore expression on items in


per_unit_instance groups. This option lets you set ignore expressions for
an instance, depending on the scope.
Like the boolean expression for the ignore option for cross items, the expr
argument for instance_ignore can contain any of the participating items
and global values. However, the instance_ignore expression also includes
an inst field. In the context of an explicit per-unit instance or for cover
groups defined under a struct or unit, the inst field contains a pointer to the
unit defined by the per_unit_instance option. In the case of an implicit
per-unit instance collection of cover groups defined under units, the inst
field refers to the enclosing unit.
The fields used in the expression should remain constant throughout the
run. Otherwise, false holes can occur in the coverage results. Furthermore,
when an instance_ignore expression is defined for an item, its unit type
must be known and cannot change after the definition. As a result:

Specman e Language Reference


1999-2015

For a cover group defined inside a struct, an instance_ignore expression


cannot be defined for one of its items before the per_unit_instance is
defined for the cover group.
After an instance_ignore expression is defined for a cover group item,
the per_unit_instance type cannot be changed.

774

Product Version 15.1


All Rights Reserved.

Table 16-3

Cross Coverage Item Options, continued

Option

Description

instance_illegal=expr

Define a context-dependent illegal expression on items in


per_unit_instance groups. This option lets you set illegal expressions for
an instance, depending on the scope.
Like the boolean expression for the ignore option for cross items, the expr
argument for instance_illegal can contain any of the participating items and
global values. However, the instance_illegal expression also includes an
inst field. In the context of an explicit per-unit instance or for cover groups
defined under a struct or unit, the inst field contains a pointer to the unit
defined by the per_unit_instance option. In the case of an implicit per-unit
instance collection of cover groups defined under units, the inst field refers
to the enclosing unit.
The fields used in the expression should remain constant throughout the
run. Otherwise, false holes can occur in the coverage results. Furthermore,
when an instance_illegal expression is defined for an item, its unit type
must be known and cannot change after the definition. As a result:

For a cover group defined inside a struct, an instance_illegal expression


cannot be defined for one of its items before the per_unit_instance is
defined for the cover group.
After an instance_illegal expression is defined for a cover group item,
the per_unit_instance type cannot be changed.

Specman e Language Reference


1999-2015

775
.

Product Version 15.1


All Rights Reserved.

Table 16-3

Cross Coverage Item Options, continued

Option

Description

instance_no_collect=
expr

Define a context-dependent no_collection expression on items in


per_unit_instance groups. This option lets you set no_collection
expressions for an instance, depending on the scope.
The expr argument for instance_no_collect can include an inst field. In the
context of an explicit per-unit instance or for cover groups defined under a
struct or unit, the inst field contains a pointer to the unit defined by the
per_unit_instance option. In the case of an implicit per-unit instance
collection of cover groups defined under units, the inst field refers to the
enclosing unit.
When an instance_no_collection expression is defined for an item, its unit
type must be known and cannot change after the definition. As a result:

For a cover group defined inside a struct, an instance_no_collection


expression cannot be defined for one of its items before the
per_unit_instance is defined for the cover group.
After an instance_no_collection expression is defined for a cover group
item, the per_unit_instance type cannot be changed.

name=label

Specifies a name for a cross coverage item. No white spaces are allowed in
the label. The default is cross__item-a__item-b.

no_collect=bool

When no_collect[=TRUE], this coverage item is not displayed in coverage


reports and is not saved in the coverage files.
The primary use of this option is to specify cover items whose coverage
grades are of no interest, but whose cross coverage grade is desired. For
example:
cross a,b using no_collect;//Not interested in a cross b
cross x,y using no_collect;//Not interested in x cross y
cross cross__a__b, cross__x__y// Interested in the cross
// of a,b and x,y

This option also enables tracing of coverage information and enables event
viewing with trace event, without saving the coverage information. Setting
this option to TRUE overrides the global config cover mode setting of on
or on_interactive.
You can use using also no_collect=FALSE to override a previous setting
of no_collect[=TRUE].
Specman e Language Reference
1999-2015

776

Product Version 15.1


All Rights Reserved.

Table 16-3

Cross Coverage Item Options, continued

Option

Description

text=string

A text description for this coverage item. This can only be a quoted string,
not a variable or expression. For text-mode Specman, the text is shown
along with the item name at the top of the coverage information for the
item. In the Show Coverage GUI, the text is shown at the top of the display
for the item.

weight=uint

Specifies the weight of the current cross item relative to other items in the
same coverage group. It is a non-negative integer with a default of 1.

when=bool-exp

The item is sampled only when bool-exp is TRUE. The bool-exp is


evaluated in the context of the parent struct.

Description
Defines cross coverage between items in the same coverage group. Creates a new item with a name
specified using a name option, or with a default name of cross__item-name-1__item-name-2 (with
two underscores separating the parts of the name). This shows every combination of values of the first
and second items, and every combination of the third item and the first item, the third item and the
second item, and so on.
You can cross any combination of basic coverage items, cross items, and transitions defined in the same
coverage group.
When there is a hole in one of the items of a cross, the whole branch of samples that is spawned under
the hole is, by default, omitted from the coverage report. To see the full report, including all the holes,
set the coverage configuration show_sub_holes to TRUE.

Note
You can view cross coverage interactively using the Show Coverage GUI or the show coverage
command, between items in the same coverage group or in several groups.

See Also

Defining Coverage for Real Numbers in Managing Coverage for e Testbenches

Example 1
In the following example, cross coverage is collected for the three coverage items op1, op2, and
opcode. Constraints are applied to limit opcode values to either ADD or SUB, to limit op1 values
to reg0 or reg1, and to limit op2 values to the range 1 to 24.
Specman e Language Reference
1999-2015

777
.

Product Version 15.1


All Rights Reserved.

The coverage group is named inst_driven. The inst_driven event is emitted elsewhere in the code
whenever an instruction is generated.
The op2 coverage item definition uses the ranges option with a range of 1 to 16 and every-count
equal to 4. This creates a bucket for values 1 to 16, which is divided into four smaller buckets for values
from 1 to 4, 5 to 8, 9 to 12, and 13 to 16. Values from 17 to 24 go into the default others bucket, since
they are not in the specified range.
The coverage report will show holes for all instances of opcode that are not ADD or SUB, and for
all instances of op1 that are not reg0 or reg1.
type cpu_opcode: [ADD, SUB, OR, AND, JMP, LABEL];
type cpu_reg: [reg0, reg1, reg2, reg3];
struct inst {
opcode: cpu_opcode;
keep opcode in [ADD, SUB];
op1: cpu_reg;
keep op1 in [reg0, reg1];
op2: byte;
keep op2 in [1..24];
event inst_driven;
cover inst_driven is {
item opcode;
item op1;
item op2 using ranges = {range([1..16], "", 4)};
cross opcode, op1, op2 using name = opcode_op1_op2;
};
};

The cross of opcode, op1, and op2 shows all the combinations of values for those three items, sorted first
by opcode value, by op1 under each opcode value, and by op2 under each op1 value.
For a sample test in which 10 instances of the inst struct were generated, the item values are shown in
Figure 16-1 on page 778, and a chart of the cross coverage information is shown in Figure 16-2 on page
779.
The data shown in Figure 16-2 on page 779 is shown again in Figure 16-3 on page 780, as displayed by
the show cover command.
In GUI mode, you can view a graphical view of the data by opening the Show Coverage GUI.
Figure 16-1

Description of Generated Instances of inst

instance

opcode

op1

op2

SUB

reg0

18

SUB

reg0

18

Specman e Language Reference


1999-2015

778

Product Version 15.1


All Rights Reserved.

ADD

reg0

17

ADD

reg0

SUB

reg1

ADD

reg0

14

ADD

reg1

16

SUB

reg0

13

SUB

reg1

10

ADD

reg1

Figure 16-2

Cross Coverage Sample Results


op2 in 1-4 (1 time, value: 1)
op2 in 5-8 (0 times)
op1=reg0 (3 times)

op2 in 9-12 (0 times)


op2 in 13-16 (1 time, value: 14)
op2 in 17-24 (1 time, value: 17)

opcode=ADD (5 times)
op2 in 1-4 (1 time, value: 1)
op2 in 5-8 (0 times)
op1=reg1 (2 times)

op2 in 9-12 (0 times)


op2 in 13-16 (1 time, value: 16)
op2 in 17-24 (0 times)
op2 in 1-4 (0 times)
op2 in 5-8 (0 times)

op1=reg0 (3 times)

op2 in 9-12 (0 times)


op2 in 13-16 (1 time, value: 13)
op2 in 17-24 (2 times, values: 18, 18)

opcode=SUB (5 times)
op2 in 1-4 (1 time, value: 4)
op2 in 5-8 (1 time, value: 6)
op1=reg1 (2 times)

op2 in 9-12 (0 times)


op2 in 13-16 (0 times)
op2 in 17-24 (0 times)

Specman e Language Reference


1999-2015

779
.

Product Version 15.1


All Rights Reserved.

Figure 16-3

Cross Coverage Example Results Displayed by show cover

** cross__opcode__op1__op2 **
Samples: 10 Tests: 1 Grade: 0.07
grade

goal

0.25
0.50
1.00
0.00
0.00
1.00
]
NA
0.50
1.00
0.00
0.00
1.00
]
0.00
0.00
0.19
0.25
0.00
0.00
0.00
1.00
]
NA
0.50
1.00
1.00
0.00
0.00
]
0.00
0.00

Weight: 1

samples

tests

%p/%t

opcode/op1/op2

1
1
1
1

5
3
1
0
0
1

1
1
1
0
0
1

50/50
60/30
33/10
0/0
0/0
33/10

ADD
ADD/reg0
ADD/reg0/[1..4]
ADD/reg0/[5..8]
ADD/reg0/[9..12]
ADD/reg0/[13..16

0
1
1
1
1

1
2
1
0
0
1

1
1
1
0
0
1

33/10
40/20
50/10
0/0
0/0
50/10

ADD/reg0/others
ADD/reg1
ADD/reg1/[1..4]
ADD/reg1/[5..8]
ADD/reg1/[9..12]
ADD/reg1/[13..16

1
1
1
1

0
0
5
3
0
0
0
1

0
0
1
1
0
0
0
1

0/0
0/0
50/50
60/30
0/0
0/0
0/0
33/10

ADD/reg2
ADD/reg3
SUB
SUB/reg0
SUB/reg0/[1..4]
SUB/reg0/[5..8]
SUB/reg0/[9..12]
SUB/reg0/[13..16

0
1
1
1
1

2
2
1
1
0
0

1
1
1
1
0
0

67/20
40/20
50/10
50/10
0/0
0/0

SUB/reg0/others
SUB/reg1
SUB/reg1/[1..4]
SUB/reg1/[5..8]
SUB/reg1/[9..12]
SUB/reg1/[13..16

0
0

0
0

0/0
0/0

SUB/reg2
SUB/reg3

Specman e Language Reference


1999-2015

780

Product Version 15.1


All Rights Reserved.

Example 2
The example below shows the name option. For all occurrences of the opcode item together with the
op1 item, the coverage report shows the cross item name and its definition, code_and_reg (cross
opcode, op1).
type cpu_opcode: [ADD, SUB, OR, AND, JMP, LABEL];
type cpu_reg: [reg0, reg1, reg2, reg3];
struct inst {
opcode: cpu_opcode;
op1: cpu_reg;
event inst_driven;
cover inst_driven is {
item opcode;
item op1;
cross opcode, op1 using name = code_and_reg;
};
};

Example 3
The example below shows how to define cross coverage for two items sampled at different events. The
events named request and grant are driven by HDL signals of the same names. The event named
cov_req_ack occurs whenever a grant event follows a request event by any number of cycles in which
request does not occur. Upon a request event, the request_type field is assigned the value of the HDL
req_type signal, by the exec expression. Thus, the request_type field gets its value upon occurrence of
the request event. This can be thought of as sampling request_type on the request event.
Since the cover_req_ack event occurs when grant occurs (when the sequence in the cov_req_ack
definition succeeds), the items in the cov_req_ack group are sampled upon the occurrence of grant. Thus
the request_type item depends on both the request event and the grant event, and the burst_mode item
depends on the grant event. This has the effect of sampling request_type on the request event, and
sampling burst_mode on the grant event.
struct monitor {
request_type: uint;
event request is rise('top.request')@sim;
event grant is rise('top.grant')@sim;
event cov_req_ack is {
@request exec {request_type = 'top.req_type';};
[..]* not @request;
@grant;
} @sys.clk;
cover cov_req_ack is {
item request_type using
Specman e Language Reference
1999-2015

781
.

Product Version 15.1


All Rights Reserved.

ranges = {
range([0..3], "", 1);
range(others, "invalid")
};
item burst_mode: bool = 'top.burst_mode';
cross request_type, burst_mode;
};
};

Example 4
The example below shows cross coverage per instance. The alu item is defined as a per_instance item,
so coverage is collected for the cross of opcode and operand1 when alu==ALU_0 and when
alu==ALU_1.
struct instruction {
alu: [ALU_0, ALU_1];
opcode: [ADD, SUB, AND, XOR];
operand1 : byte;
operand2 : byte;
event stimulus;
cover stimulus is {
item alu using per_instance;
item opcode;
item operand1;
cross opcode, operand1;
};
};

Example 5
The example below shows how to extend a cross coverage item. In this case, the cross item, cross
opcode, operand1, is initially defined without the name option, so the default name,
cross__opcode_operand1, is required in the extension. If the cross item is initially defined using the
name option, the given name is used in place of the default name. For additional information about
extending coverage items, see Extending Coverage Items on page 805.
struct instruction {
alu: [ALU_0, ALU_1];
opcode: [ADD, SUB, AND, XOR];
operand1 : byte;
operand2 : byte;
event stimulus;
Specman e Language Reference
1999-2015

782

Product Version 15.1


All Rights Reserved.

cover stimulus is {
item opcode;
item operand1;
cross opcode, operand1;
};
};
extend instruction {
cover stimulus is also {
item cross__opcode__operand1 using also text =
"Cross of opcode and operand1";
};
};

Example 6
The example below shows a cross of two cross items. The items alu and operand1 are crossed, and the
items opcode and operand2 are crossed, and then those two cross items are crossed.
struct instruction {
alu: [ALU_0, ALU_1];
opcode: [ADD, SUB, AND, XOR];
operand1 : byte;
operand2 : byte;
event stimulus;
cover stimulus is {
item alu;
item opcode;
item operand1;
item operand2;
cross alu, operand1 using name=x_alu_op1;
cross opcode, operand2 using name=x_opc_op2;
cross x_alu_op1, x_opc_op2;
};
};

Example 7
This example defines a cover group, done, which collects cross coverage for items x and y, except for
those instances where the sum of x and y is greater than a specified maximum value; those results are
ignored. For the alu1 instance, the maximum value is 6; for alu2, it is 4.

When you view the cross__x__y coverage data for alu1, it includes buckets for all possible
combinations of x and y where their sum is less than 6.

Specman e Language Reference


1999-2015

783
.

Product Version 15.1


All Rights Reserved.

For alu2, cross__x__y has buckets for all possible combinations of x and y where their sum is less
than 4.

Holes in the coverage data are indicated by a 0% overall grade.


<
struct add_instruction {
x: uint(bits:3);
y: uint(bits:3);
event done;
cover done using per_unit_instance=alu is{
item x using no_collect;
item y using no_collect;
cross x, y using instance_ignore= (x + y > inst.max_sum);
};
cover done(per_type) using also no_collect; // not intersted in per_type
results
};
unit alu{
max_sum: uint(bits:3);
add_inst_list: list of add_instruction;
keep add_inst_list.size() == 20;
keep for each in add_inst_list{
it.x + it.y <= max_sum;
};
run() is also{
for each in add_inst_list{
// do something
emit it.done;
};
};
};
extend sys{
alu1: alu is instance;
keep alu1.max_sum == 6;
alu2: alu is instance;
keep alu2.max_sum == 4;
};
'>

Example 8
unit u{
max_x_val: uint(bits:3);
max_y_val: uint(bits:3);
allow_x_eq_y: bool;
Specman e Language Reference
1999-2015

784

Product Version 15.1


All Rights Reserved.

x: uint(bits:3);
keep x <= max_x_val;
y: uint(bits:3);
keep y <= max_y_val;
when FALSE'allow_x_eq_y{
keep x != y;
};
event ev;
cover ev
item
item
cross

using per_unit_instance is{


x using instance_illegal=(x > inst.max_x_val);
y using instance_illegal=(y > inst.max_y_val);
x,y using instance_illegal=(not inst.allow_x_eq_y) and (x ==

y);
};
};
extend sys{
u1: u is instance;
keep u1.allow_x_eq_y;
u2: u is instance;
keep not u2.allow_x_eq_y;
};

16.4 Defining Transition Coverage Items


Transition items are items for which value changes are collected in the coverage data. The transition
coverage group item is used to define transition items.

16.4.1

transition

Purpose
Define a coverage transition item

Category
Coverage group item

Specman e Language Reference


1999-2015

785
.

Product Version 15.1


All Rights Reserved.

Syntax
transition item-name [using coverage-item-option, ...]
Syntax Example
cover state_change is {
item st: cpu_state = 'top.cpu.main_cur_state';
transition st;
};

Parameters
item-name

A coverage item defined previously in the current coverage group.

coverage-item-option

The coverage item options are listed in Table 16-4.

Table 16-4

Transition Coverage Item Options

Option

Description

at_least=num

A non-negative integer specifying the minimum number of samples for


each bucket of each of the transition items. Anything less than num is
considered a hole. The default is 1.
This option cannot be used with string items or for unconstrained integers
(items that have no specified ranges).

Specman e Language Reference


1999-2015

786

Product Version 15.1


All Rights Reserved.

Table 16-4

Transition Coverage Item Options, continued

Option

Description

ignore=item-bool-exp

Define values that are to be completely ignored. They do not appear in the
statistics at all. The expression is a Boolean expression that can contain a
coverage item name and constants.
The previous value can be accessed as prev_item-name. The prev prefix is
predefined for this purpose.
The Boolean expression is evaluated in a global context, not in instances of
the struct. In other words, the expression must be valid at all times, even
before generation. Therefore, you can only use constants and the item itself
in the expression. In a cross, that means any of the participating items. In a
transition, that means the item or prev_item.
For example, if i is a coverage item and j is a reference to a struct field,
the expression i > 5 is a valid expression, but i > me.j is not legal.
Using ignore has two effects:
1.

If the ignore expression is TRUE when the data is sampled, the sampled
value is ignored (that is, not added to the bucket count).

2.

When you view the results with show cover or with the coverage GUI,
Specman queries the ignore expression for each hole in the coverage
results. If the ignore expression is TRUE:

The bucket is hidden, rather than identified as a hole.


Coverage grades are computed without taking into account the
bucket contents.
If you want to achieve the first effect (ignore specific samples), but you do
not want to hide buckets containing holes and you want the grade to reflect
all generated values, use the when option instead. This description also
appears in the basic and cross item descriptions.

See Analyzing the Effects of the ignore and illegal Options in Managing
Coverage for e Testbenches for more information about the effects of the
ignore option.
Note You can use the show cover -space command to reports the
number of legal buckets defined for the item versus the number of buckets
that would be defined if the illegal and ignore coverage options did not
apply.

Specman e Language Reference


1999-2015

787
.

Product Version 15.1


All Rights Reserved.

Table 16-4

Transition Coverage Item Options, continued

Option

Description

illegal=item-bool-exp

Define values that are illegal. An illegal value causes a DUT error. If the
check_illegal_immediately coverage configuration option is FALSE, the
DUT error occurs during the check_test phase of the test. If that
configuration option is TRUE, the DUT error occurs immediately (on the
fly). Note that checking illegal values immediately has a significant
negative impact on Specman performance.
See illegal on page 765 for an example of how to set the error effect of this
check to WARNING instead of ERROR.
The Boolean expression is evaluated in a global context, not in instances of
the struct. In other words, the expression must be valid at all times, even
before generation. Therefore, you can only use constants and the item itself
in the expression. In a transition, that means the item or prev_item.
For example, if i is a coverage item and j is a reference to a struct field,
the expression i > 5 is a valid expression, but i > me.j is not legal.
When you view result with show cover or the coverage GUI, Specman
queries the illegal expression. If the illegal expression is TRUE, coverage
grades are computed without taking into account the bucket contents.
If, on the other hand, you want the coverage grades to reflect all bucket
contents, use the when option instead to specify the circumstances under
which a given value is counted. This description also appears in the basic
and cross item descriptions (last sentence in third para is different in each
description).
See Analyzing the Effects of the ignore and illegal Options in Managing
Coverage for e Testbenches for more information about the effects of the
illegal option.
Note You can use the show cover -space command to reports the
number of legal buckets defined for the item versus the number of buckets
that would be defined if the illegal and ignore coverage options did not
apply.

Specman e Language Reference


1999-2015

788

Product Version 15.1


All Rights Reserved.

Table 16-4

Transition Coverage Item Options, continued

Option

Description

instance_ignore=exp
r

Define a context-dependent ignore expression on items in


per_unit_instance groups. This option lets you set ignore expressions for
an instance, depending on the scope.
Like the boolean expression for the ignore option for transition items, the
expr argument for instance_ignore can contain the item, prev_item, and
global values. However, the instance_ignore expression also includes an
inst field. In the context of an explicit per-unit instance or for cover groups
defined under a struct or unit, the inst field contains a pointer to the unit
defined by the per_unit_instance option. In the case of an implicit per-unit
instance collection of cover groups defined under units, the inst field refers
to the enclosing unit.
The fields used in the expression should remain constant throughout the
run. Otherwise, false holes can occur in the coverage results. Furthermore,
when an instance_ignore expression is defined for an item, its unit type
must be known and cannot change after the definition. As a result:

For a cover group defined inside a struct, an instance_ignore expression


cannot be defined for one of its items before the per_unit_instance is
defined for the cover group.
After an instance_ignore expression is defined for a cover group item,
the per_unit_instance type cannot be changed.

Specman e Language Reference


1999-2015

789
.

Product Version 15.1


All Rights Reserved.

Table 16-4

Transition Coverage Item Options, continued

Option

Description

instance_illegal=expr

Define a context-dependent illegal expression on items in


per_unit_instance groups. This option lets you set illegal expressions for
an instance, depending on the scope.
Like the boolean expression for the illegal option for transition items, the
expr argument for instance_illegal can contain the item, prev_item, and
global values. However, the instance_illegal expression also includes an
inst field. In the context of an explicit per-unit instance or for cover groups
defined under a struct or unit, the inst field contains a pointer to the unit
defined by the per_unit_instance option. In the case of an implicit per-unit
instance collection of cover groups defined under units, the inst field refers
to the enclosing unit.
The fields used in the expression should remain constant throughout the
run. Otherwise, false holes can occur in the coverage results. Furthermore,
when an instance_illegal expression is defined for an item, its unit type
must be known and cannot change after the definition. As a result:

Specman e Language Reference


1999-2015

For a cover group defined inside a struct, an instance_illegal expression


cannot be defined for one of its items before the per_unit_instance is
defined for the cover group.
After an instance_illegal expression is defined for a cover group item,
the per_unit_instance type cannot be changed.

790

Product Version 15.1


All Rights Reserved.

Table 16-4

Transition Coverage Item Options, continued

Option

Description

instance_no_collect=
expr

Define a context-dependent no_collect expression on items in


per_unit_instance groups. This option lets you set no_collect expressions
for an instance, depending on the scope.
The expr argument for instance_no_collect can include an inst field. In the
context of an explicit per-unit instance or for cover groups defined under a
struct or unit, the inst field contains a pointer to the unit defined by the
per_unit_instance option. In the case of an implicit per-unit instance
collection of cover groups defined under units, the inst field refers to the
enclosing unit.
When an instance_no_collect expression is defined for an item, its unit
type must be known and cannot change after the definition. As a result:

For a cover group defined inside a struct, an instance_no_collect


expression cannot be defined for one of its items before the
per_unit_instance is defined for the cover group.
After an instance_no_collect expression is defined for a cover group
item, the per_unit_instance type cannot be changed.

name=string

Specifies a name for a transition coverage item. The default name is


transition__item-name (where two underscores separate transition and
item-name).

no_collect=bool

When no_collect[=TRUE], this coverage item is not displayed in coverage


reports and is not saved in the coverage files.
The primary use of this option is to specify cover items whose coverage
grades are of no interest, but whose cross coverage grade is desired. For
example:
item st using no_collect; // Not interested in st grade
transition st; //Interested in transitions of st

This option also enables tracing of coverage information and enables event
viewing with trace event, without saving the coverage information. Setting
this option to TRUE overrides the global config cover mode setting of on
or on_interactive.
You can use using also no_collect=FALSE to override a previous setting
of no_collect[=TRUE].

Specman e Language Reference


1999-2015

791
.

Product Version 15.1


All Rights Reserved.

Table 16-4

Transition Coverage Item Options, continued

Option

Description

per_instance=bool

When per_instance[=TRUE], coverage data is collected and graded for all


the other items in a separate sub-group for each bucket of this item. This
option can only be used for gradeable items.
When you use per_instance with transition coverage, the per_type
transition collects all transitions, including the cross-instances ones. If there
are two instances OP_1 and OP_2, and the following values are assigned to
them:
OP_1 = A
OP_2 = B

then the per_type transition item includes the transition A->B. To disable
false illegal notification that occurs across instances, you must turn off the
transition item of the per_type coverage. See Example 6 on page 795.
If you want to see all the true transitions, but you are not interested in
which instance has experienced each one, you should use a cross item with
using when, instead of using a combination of per_instance and transition.
See Example 7 on page 795.
text=string

A text description for this coverage item. This can only be a quoted string,
not a variable or expression. For text-mode Specman, the text is shown
along with the item name at the top of the coverage information for the
item. In the Show Coverage GUI, the text is shown at the top of the item.

weight=uint

Specifies the weight of the current transition item relative to other items in
the same coverage group. It is a non-negative integer with a default of 1.

when=bool-exp

The item is sampled only when bool-exp is TRUE. The bool-exp is


evaluated in the context of the parent struct.

Description
Defines coverage for changes from one value to another of a coverage item. If no name is specified for
the transition item with the name option, it gets a default name of transition__item-name (with two
underscores between transition and item-name). If item-name had n samples during the test, then the
transition item has n-1 samples, where each sample has the format previous-value, value.

Specman e Language Reference


1999-2015

792

Product Version 15.1


All Rights Reserved.

Example 1
Any change from the previous value of st to the current value of st that is not one of the listed
changes is illegal and causes a DUT error during check_test. This example uses the prev_item-name
syntax, which refers to the previous value of the item (st in this case).
type cpu_state: [START, FETCH1, FETCH2, EXEC];
struct cpu {
st: cpu_state;
event state_change is
change('top.cpu.main_cur_state') @sim;
cover state_change is {
item st;
transition st using illegal =
not ((prev_st == START and st == FETCH1)
or (prev_st == FETCH1 and st == FETCH2)
or (prev_st == FETCH1 and st == EXEC)
or (prev_st == FETCH2 and st == EXEC)
or (prev_st == EXEC and st == START));
};
};

Example 2
The example below shows the name option. For all transitions of the st item, the coverage report
shows the item name and its definition, st_change (transition st).
type cpu_state: [START, FETCH1, FETCH2, EXEC];
struct cpu {
st: cpu_state;
event state_change is
change('top.cpu.main_cur_state') @sim;
cover state_change is {
item st;
transition st using name = st_change;
};
};

Example 3
The example below shows transition coverage of a cross coverage item (see Defining Cross Coverage
Items on page 769).
struct instruction {
alu: [ALU_0, ALU_1];
Specman e Language Reference
1999-2015

793
.

Product Version 15.1


All Rights Reserved.

opcode: [ADD, SUB, AND, XOR];


operand1 : byte;
operand2 : byte;
event stimulus;
cover stimulus is {
item alu;
item opcode;
item operand1;
item operand2;
cross opcode, operand1 using name=x_opc_op1;
transition x_opc_op1;
};
};

Example 4
The example below shows transition coverage per instance. The alu item is defined as a per_instance
item, so coverage is collected for the opcode transitions when alu==ALU_0 and when alu==ALU_1.
struct instruction {
alu: [ALU_0, ALU_1];
opcode: [ADD, SUB, AND, XOR];
operand1 : byte;
operand2 : byte;
event stimulus;
cover stimulus is {
item alu using per_instance;
item opcode;
transition opcode;
};
};

Example 5
The example below shows how to extend a transition coverage item. In this case, the transition item,
transition opcode, is initially defined without the name option, so the default name,
transition__opcode, is required in the extension. If the transition item is initially defined using the
name option, the given name is used in place of the default name. For additional information about
extending coverage items, see Extending Coverage Items on page 805.
struct instruction {
alu: [ALU_0, ALU_1];
opcode: [ADD, SUB, AND, XOR];
Specman e Language Reference
1999-2015

794

Product Version 15.1


All Rights Reserved.

operand1 : byte;
operand2 : byte;
event stimulus;
cover stimulus is {
item opcode;
item operand1;
transition opcode;
};
};
extend instruction {
cover stimulus is also {
item transition__opcode using also at_least = 2;
};
};

Example 6
In order to see transitions over each instance separately, and not see false illegal notifications that occur
across the instances, you must turn off the transition item of the per_type coverage, as shown in this
example.
unit cover_u {
cover deframer_fsm is {
item pi_name using per_instance;
item deframer_state;
transition deframer_state using
illegal = not((deframer_state == RESET
and prev_deframer_state == HALT)
or (deframer_state == RUNNING
and prev_deframer_state == HALT));
};
cover deframer_fsm(per_type) is also {
-- to disable combined transition
item transition__deframer_state using also illegal=FALSE, no_collect;
};
};

Example 7
If you want to see all the true transitions, but you are not interested in which instance has experienced
each one, you should use a cross item with using when, instead of using a combination of per_instance
and transition.
Specman e Language Reference
1999-2015

795
.

Product Version 15.1


All Rights Reserved.

type op_t : [a,b,c,d,e,f,g,h,i];


unit alu {
!alu_cov_ctr : uint; // inits to 0
opcode : op_t;
temp_op : op_t;
prev_op : op_t;
event alu_cov;
on alu_cov {
prev_op = temp_op; // pipelining the previous value
temp_op = opcode;
alu_cov_ctr += 1; // counting the instance cov events
};
cover alu_cov is {
item opcode;
item prev_op using no_collect;
cross prev_op, opcode using when = alu_cov_ctr > 1;
};
};
extend sys {
alu1 : alu is instance;
keep alu1.opcode in [a,b,c];
alu2 : alu is instance;
keep alu2.opcode in [d,e,f];
alu3 : alu is instance;
keep alu3.opcode in [g,h,i];
runner() @sys.any is {
for i from 1 to 1000 {
gen alu1.opcode;
gen alu2.opcode;
gen alu3.opcode;
emit alu1.alu_cov;
emit alu2.alu_cov;
emit alu3.alu_cov;
wait cycle;
};
stop_run();
};
run() is also {
start runner();
};
};

Specman e Language Reference


1999-2015

796

Product Version 15.1


All Rights Reserved.

Example 8
This example defines a cover group, cov, that ignores instances if can_keep_state is false and the next
state is equal to the previous state. When you run this example, it creates 9 binsone for each possible
state transition. Instance fsm1 reports all 9 bins, but fsm2 does not report those bins where the next state
equals the previous state; those bins are ignored.
<'
type state_t: [S1, S2, S3];
unit fsm {
state: state_t;
can_keep_state: bool;
event cov;
cover cov using per_unit_instance is{
item state using no_collect;
transition state using instance_ignore=((not inst.can_keep_state) and
(prev_state==state));
};
run() is also{
for i from 1 to 10{
if can_keep_state{
gen state;
}else{
var pstate: state_t = state;
gen state keeping {it != pstate};
};
emit cov;
};
};
};
extend sys{
fsm1: fsm is instance;
keep fsm1.can_keep_state;
fsm2: fsm is instance;
keep not fsm2.can_keep_state;
};
'>

See Also

Defining Coverage Groups on page 735

Defining Basic Coverage Items on page 745

Specman e Language Reference


1999-2015

797
.

Product Version 15.1


All Rights Reserved.

Extending Coverage Items on page 805

16.5 Extending Coverage Groups


16.5.1

cover ... using also ... is also

Purpose
Extend a coverage group

Category
Struct member

Syntax
cover event-type[(instance-identifier)]
[using also coverage-option, ...]
[is also {coverage-item-definition; ... } ]
Syntax examples:
cover rclk is also {
item rflag;
};
cover rclk using also text = "RX clock";
cover rclk using also no_collect is also {
item rvalue;
};

Parameters
event-type

The name of the coverage group. This must be an event defined previously
in the struct. The event is the sampling event for the coverage group.

Specman e Language Reference


1999-2015

798

Product Version 15.1


All Rights Reserved.

(instance-identifier)

One of the following:

per_type (the default)


per_instance sub-group name. Syntax:
item-name == bucket-name

per_unit_instance instance name. Syntax:


e_path == e-path
or
instance-name, as defined in Using Logical Instance Names in
per_unit_instance Coverage in Specman Early Adopter Features

Wildcards are allowed.


coverage-option

Coverage options are listed in Table 16-1 on page 737 and Table 16-2 on
page 747.

coverage-itemdefinition

The definition of a coverage item. Coverage items are described in Defining


Basic Coverage Items on page 745.

Description
The using also clause changes, overrides, or extends options previously defined for the coverage group.
The is also clause adds new items to a previously defined coverage group, or can be used to change the
options for previously defined items. See Extending Coverage Items on page 805.
If a coverage group is defined under a when subtype, it can only be extended under that subtype.
In an extension of a cover group, if you override a cover group when option, then the overriding
condition is only considered after the condition in the base group is satisfied. That is, sampling of the
item is only performed when the logical AND of the cover group when options is true.
The prev Variable
When you use using also to extend or change a when, illegal, or ignore option, a special variable named
prev is automatically created. The prev variable holds the results of all previous when, illegal, or
ignore options, so you can use it as a shorthand to assert those previous options combined with a new
option value. For example, if a base struct cover group definition has when = size == 5, and an
extension has using also when = (prev and size <= 10), the result is the same as when = (size == 5 and
size <= 10).

Specman e Language Reference


1999-2015

799
.

Product Version 15.1


All Rights Reserved.

Extending per_instance Coverage


You can extend coverage for a per-instance coverage sub-group defined with the per_instance option.
To do so, enter the instance sub-group name as the instance-identifier. For example, if a cover group
named done contains a cover item named packet that has buckets named Ethernet and ATM, use
cover done(packet==ATM) is also {...} to extend the cover group in ATM instances.
Note also the following:

If you extend a coverage group in a when construct by adding a per-instance item, then the sub-groups
refer only to the when subtype. If you define a per-instance item in a base type and then add additional
items under when construct, then the item instance sub-groups refer to the base type, and the cover
item values refer to the when subtype. See Collecting Separate Coverage Data for Item Instances in
Managing Coverage for e Testbenches.
If you extend a sub-group that never gets created (due to an ignore or illegal option), a warning is
issued and no information for the extension is put in the coverage data.
If you change the coverage options of a sub-group, the coverage data for the per-type item might no
longer reflect or agree with the per-instance coverage data.
If you extend a sub-group using an illegal sub-group name, the extension is ignored. In particular,
be careful to express the sub-group name in decimal radix, even if another radix is defined for the
group or item. For more information, see Sub-Group Names and the Item Radix in Managing
Coverage for e Testbenches.

Extending per_unit_instance Coverage


You can extend coverage for a coverage group instance defined with the per_unit_instance option. To
do so, enter the e path identifier as the instance-identifier. (If you defined the instance-identifier with the
Early Adopter logical name feature described in Using Logical Instance Names in per_unit_instance
Coverage in Specman Early Adopter Features, enter the instance logical name as the
instance-identifier.)
For example, if the cover group is named transfer_ended, the instance-identifier was defined with an
e path, and the unit instances to which the cover group applies are sys.a1 and sys.a2, use the following
code to extend coverage for the a1 instance:
cover transfer_ended(e_path==sys.a1) is also {...}

Note also the following:

If you extend a unit that is not instantiated, a warning is issued at elaboration time, and the extension
has no effect. The warning is a notification named
WARN_PER_INSTANCE_EXTEND_NOT_FOUND.
This might happen if, for example, the e path or logical name you entered is wrong or you entered
an e path when the instance-identifier was defined with a logical name (or vice-versa).

Specman e Language Reference


1999-2015

800

Product Version 15.1


All Rights Reserved.

If you change the coverage options of a cover group instance, the coverage data for the per-type item
might no longer reflect or agree with the per-instance coverage data.

Example 1

Extending a Base Coverage Group

The following example extends a coverage group named info by adding two cover items, op2 and
cross op1, op2.
struct op_st {
op1: byte;
op2: byte;
event info;
cover info is {
item op1;
};
};
extend op_st {
cover info is also {
item op2;
cross op1, op2;
};
};

Example 2

Extending per_instance Coverage

In the following example, the cover done extension in the inst struct extension adds text to the cover
group named done, and adds a new item named interrupt to the group for instances of cpu_id==CPU_1:
type cpu_type: [CPU_1, CPU_2];
struct inst {
cpu_id: cpu_type;
cpu_on: bool;
interrupt: uint(bits:2);
event done;
cover done is {
item cpu_id using per_instance;
item cpu_on;
};
run() is also {
emit done;
};
};
extend inst {
cover done(cpu_id==CPU_1) using also text="CPU #1" is also {
item interrupt;
};
Specman e Language Reference
1999-2015

801
.

Product Version 15.1


All Rights Reserved.

};

Example 3

Extending per_unit_instance Coverage

Three instances are included in the coverage report for the following example:

agent.transfer_ended - with two buckets for the item cmd: RD, WR

agent.transfer_ended(e_path==sys.a1) - with only the RD bucket for the item cmd

agent.transfer_ended)e_path==sys.a2) - with two buckets (RD,WR) for the item cmd

Note

For examples showing the use of logical names, rather than e paths, for the instance name, see

Using Logical Instance Names in per_unit_instance Coverage in Specman Early Adopter Features. Using

logical names instead of e paths results in code that is more reusable.


type cmd_type: [RD,WR];
unit agent {
cmd: cmd_type;
event transfer_ended;
cover transfer_ended using per_unit_instance is {
item cmd;
};
cover transfer_ended(e_path==sys.a1) is also {
item cmd using also ignore=(cmd==WR);
};
};
extend sys {
a1: agent is instance;
a2: agent is instance
};

Example 4

Extending to Cancel the global Option

In the following example, the using also is used to cancel the global option:
struct packet{
len: uint (bits: 4);
kind: bool;
event packet_gen;
cover packet_gen using global is {
item len;
item kind;
cross len, kind using text = "cross_l_k";
};
Specman e Language Reference
1999-2015

802

Product Version 15.1


All Rights Reserved.

};
extend packet {
cover packet_gen using also global = FALSE;
};

Example 5

Extending to Override or Narrow a when Option

The following example show how to use using also to override and to narrow a when option:
// Original definition:
struct packet{
len: uint (bits: 4);
kind: bool;
event packet_gen;
cover packet_gen using when = len >= 3 is {
item len;
};
};
// Overriding the when definition:
extend packet {
cover packet_gen using also when = len == 4;
};
// Narrowing the when definition:
extend packet {
cover packet_gen using also when = (prev and len <= 7);
};

Example 6

Extending Coverage Initially Defined under a when Subtype

This example uses using also to extend the original definition of the cover done group by adding when
= id > 64, and then uses is also to add new coverage item, port, to the coverage group. Because the
coverage group is initially defined under a when subtype, the coverage group extensions can only be
done in an extension of that subtype.
<'
struct packet {
len: uint (bits: 4);
ptype: [ATM, Eth];
good: bool;
id: byte;
port: uint (bits: 2);
event done;
when good packet {
Specman e Language Reference
1999-2015

803
.

Product Version 15.1


All Rights Reserved.

cover done is {
item len;
item ptype;
};
};
};
'>
<'
extend good packet {
cover done using also when = id > 64 is also {
item port;
};
};
'>

Example 7

Extending per_instance Coverage to Ignore the per_type Grade

The following example uses using also to set the weight of the per_type cover instance to zero so it will
not affect the overall grade.
type cpu_type: [CPU_1, CPU_2];
struct inst {
cpu_id: cpu_type;
cpu_on: bool;
event done;
cover done is {
item cpu_id using per_instance;
item cpu_on;
};
run() is also {
emit done;
};
};
extend inst {
cover done(per_type) using also weight = 0;
};

See Also

Defining Coverage Groups on page 735

Defining Basic Coverage Items on page 745

Collecting Separate Coverage Data for Item Instances in Managing Coverage for e Testbenches

Specman e Language Reference


1999-2015

804

Product Version 15.1


All Rights Reserved.

16.6 Extending Coverage Items


This includes the following:

Extending Simple Items on page 805

Extending Cross and Transition Coverage Items on page 809

See Also

Defining Coverage Groups on page 735

Defining Cross Coverage Items on page 769

Defining Transition Coverage Items on page 785

Extending Coverage Groups on page 798

16.6.1

Extending Simple Items

16.6.1.1 item ... using also


Purpose
Change or extend the options on a simple cover item.

Category
Coverage group item

Syntax
item item-name using also coverage-item-option, ...
Syntax Example
item len using also radix = HEX;

Parameters
item-name

The name you assigned to the coverage item.

coverage-itemoption

Coverage item options are listed in Table 16-2. The options can appear in any
order after the using also keyword.

Specman e Language Reference


1999-2015

805
.

Product Version 15.1


All Rights Reserved.

Description
Cover simple item extensibility allows you to extend, change, or override a previously defined coverage
item. Coverage simple item options are listed in Table 16-2.
To extend a simple coverage item, you must also use is also for its coverage group. For example:
cover event-type is also { item item-name using also ...};

See Extending Coverage Groups on page 798.


If a simple coverage item is originally defined under a when subtype, it can only be extended in the
same subtype of the base type.
If a simple item is defined with an expression assigned to it, do not include the expression when you
extend the item:
item b: bool = f(a,c) ...
item b using also ...

// Item was defined with expression f(a,c)


// Omit the type and expression in the extension

If you specify using also with the when, illegal, or ignore option more than once for a particular item,
the last using also nullifies the previous one. For example, in the following, the len > 4 condition is
disregarded; only the len < 8 condition is applied:
extend packet {
cover done is also {
item good_short using also when = (len > 4);
};
extend packet {
cover done is also {
item good_short using also when = (len < 8);
};
};

To apply using also multiple times with the when, illegal, or ignore option, you can use the special prev
variable to represent the previous conditions, as described below.
When you use using also to extend or change a when, illegal, or ignore option, a special variable named
prev is automatically created. The prev variable holds the results of all previous when, illegal, or
ignore options, so you can use it as a shorthand to assert those previous options combined with a new
option value. For example, if an original coverage item definition has when = size == 5, and an
extension has using also when = (prev and size <= 10), the result is the same as when = (size == 5 and
size <= 10).

Specman e Language Reference


1999-2015

806

Product Version 15.1


All Rights Reserved.

Example 1
In this example, an item named len is defined in the base type, then a new option, radix = HEX, is added,
and finally the option is redefined to radix = BIN.
<'
struct packet {
len: uint (bits: 4);
event done;
cover done is {
item len;
};
};
'>
<'
extend packet {
cover done is also {
item len using also radix = HEX;
};
};
'>
<'
extend packet {
cover done is also {
item len using also radix = BIN;
};
};
'>

Example 2
In this example, an item named good_short is defined using an expression involving two other fields in
the struct. The good_short coverage item is then extended by adding an at_least option. Note that the :
bool = (good == TRUE and len < 4) part of the original item definition is left out of the extension.
<'
struct packet {
len: uint (bits: 4);
good: bool;
event done;
cover done is {
item good_short: bool = (good == TRUE and len < 4);
};
};
'>
<'

Specman e Language Reference


1999-2015

807
.

Product Version 15.1


All Rights Reserved.

extend packet {
cover done is also {
item good_short using also at_least = 4;
};
};
'>

Example 3
In this example, the automatic prev variable is used to combine the coverage item option in the original
coverage group definition with a narrower definition in the coverage item extension. The combined
result is that coverage is collected for the logical AND of (len < 8 and len > 4).
<'
struct packet {
len: uint (bits: 4);
good: bool;
event done;
cover done is {
item good using when = (len < 8), at_least = 10;
};
};
'>
<'
extend packet {
cover done is also {
item good using also when = (prev and len > 4);
};
};
'>

Example 4
This example extends the done coverage group in the good packet subtype, to restrict the sampling of the
len item to when the port item is either 0 or 1.
<'
struct packet {
len: uint (bits: 4);
good: bool;
port: uint (bits: 2);
event done;
when good packet {
cover done is {
item len;
Specman e Language Reference
1999-2015

808

Product Version 15.1


All Rights Reserved.

};
};
};
'>
<'
extend good packet {
cover done is also {
item len using also when = port in [0,1];
};
};
'>

See Also

Defining Coverage Groups on page 735

Defining Basic Coverage Items on page 745

16.6.2

Extending Cross and Transition Coverage Items

16.6.2.1 (item ... using also)


Purpose
Change or extend the options on a cross or transition item.

Category
Coverage group item

Syntax
item <cross-name | transition-name> using also <options\>...
Syntax Example
cross len, kind using name = l_k;

Specman e Language Reference


1999-2015

809
.

Product Version 15.1


All Rights Reserved.

Parameters
cross-name |
transition-name

options

Name you assigned using the name cross/transition item option.


If you did not specify a name, the name is auto-assigned: For cross coverage
items: cross__<sub-item>__<sub-item>... ; for transition coverage items:
transition__<base-item>.
Cross coverage item options are listed in Table 16-3. Transition coverage
item options are listed in Table 16-4. The options can appear in any order
after the using also keyword.

Description
Cross and transition item extensibility allows you to extend, change, or override a previously defined
cross or transition coverage item. Options are listed in Table 16-3 (cross item) and Table 16-4 (transition
item).
To extend a cross or transition item, you specify a cross or transition name as the item name and use
item ... using also syntax. Format is:
item <cross-name> using also <options>
or
item <transition-name> using also <options>
For example:
item cross__parity_type__parity_error using also
instance_no_collect=inst.config.parity_type==NONE;

When extending a cross item that was defined with the name option (such as cross a, b using name =
c_a_b), use the assigned name (in this example, c_a_b):
item c_a_b using also ...

// Cross item was defined with a name

When extending a cross item that was defined without the name option (such as cross a, b), use the
cross items default name (in this example, cross__a__b):
item cross__a__b using also ...

// Cross item was defined with no name

When extending a transition item that was defined with the name option (such as transition b using
name = t_b), use the assigned name (in this example, t_b):
item t_b using also ...

// Transition item was defined with a name

When extending a transition item that was defined without the name option (such as transition b), use
the transition items default name (in this example, transition__b):

Specman e Language Reference


1999-2015

810

Product Version 15.1


All Rights Reserved.

item transition__b using also ...// Transition item was defined with no name

If you specify using also with the when, illegal, or ignore option more than once for a particular item,
the last using also nullifies the previous one.
To apply using also multiple times with the when, illegal, or ignore option, you can use the special prev
variable to represent the previous conditions, as described below.
When you use using also to extend or change a when, illegal, or ignore option, a special variable named
prev is automatically created. The prev variable holds the results of all previous when, illegal, or
ignore options, so you can use it as a shorthand to assert those previous options combined with a new
option value.

Example 1
The following shows several examples of coverage group and simple and cross coverage item
extensions, with comments explaining what each one does.
<'
struct packet {
len: uint (bits: 6);
kind: bool;
port: int (bits: 4);
event packet_gen;
// Original group and item definition:
cover packet_gen using global, text = "Packet info" is {
item len using ranges = {range([0..63], "", 16)}, at_least = 5;
item kind;
cross len, kind using name = l_k;
};
run() is also {emit packet_gen;};
};
'>
<'
extend packet {
// Cancel the global option:
cover packet_gen using also global = FALSE;
};
'>
<'
extend packet {
// Add a new illegal option to the cross item:
cover packet_gen is also {
item l_k using also illegal = len == 3;
};
};
'>

Specman e Language Reference


1999-2015

811
.

Product Version 15.1


All Rights Reserved.

<'
extend packet {
// Override the previous illegal option of the cross item:
cover packet_gen is also {
item l_k using also illegal = len == 4;
};
};
'>
<'
extend packet {
// Extend the illegal option, combining the previous definition
// (prev) with a new condition (len > 10):
cover packet_gen is also {
item l_k using also illegal = prev or (len > 10);
};
};
'>
<'
extend packet {
// Override the text option of the group, and add a weight option
// to the kind item:
cover packet_gen using also text = "Packet Information " is also {
item kind using also weight = 10;
};
};
'>
<'
extend packet {
// Add a new per_instance item to the packet_gen cover group:
cover packet_gen is also {
item port using per_instance;
};
};
'>
<'
extend packet {
// Exclude instances where the port number is 0:
cover packet_gen is also {
item port using also ignore = (port == 0);
};
};
'>
<'
extend sys {
packet_list[10]: list of packet;
};
'>

Specman e Language Reference


1999-2015

812

Product Version 15.1


All Rights Reserved.

See Also

Defining Coverage Groups on page 735

Defining Cross Coverage Items on page 769

Defining Transition Coverage Items on page 785

Extending Coverage Items on page 805

16.7 Collecting check/expect Results for Your Model


For coverage models written to ucm files, you can use the collect_checks_expects configuration option
to collect raw finish/fail data for check that actions and expect/assume members. This feature can be
used to collect raw data results for Incisive Metrics Center (IMC), Incisive Enterprise Manager, and
Specman.
Per-unit-instance and per-type coverage will be collected automatically for checks and expects that are
defined inside a unit. For checks and expects defined inside a struct, only per-type coverage will be
collected.

See Also

configure cover in the Specman Command Reference

16.7.1

Item Naming

If the check/expect has an explicit name, Specman uses it as its item name. If it does not have an explicit
name, Specman uses enclosing-struct-name_check|expect_index as the item name. For example:
1 struct packet {
2
expect ex1 is @...; // Explicit name: ex1
3
expect @...; // Unnamed: packet_expect_1
4
verify() is also{
5
check that x == 7 else dut_error(...); // Unnamed: packet_check_2
6
check y_pos that y > 0 else dut_error(...); // Explicit name: y_pos
7
};
8 };

Specman e Language Reference


1999-2015

813
.

Product Version 15.1


All Rights Reserved.

16.7.2

Counters for checks/expects

Three counters are associated with each check and expect itemchecked, finished, and failed. Each
time a check/expect achieves one of these states, a corresponding counter is incremented. Counter totals
are reported as the raw data.
Counter

check that

expect

Checked

The check executed.

The state machine associated with the


temporal expression of the expect entered
into an initial non-vacuous state.
For statements of the form A=>B, the A
condition succeeded.

Finished

The check that condition completed


successfully.

The temporal expression of the expect


condition completed successfully.

Failed

The check that condition failed.

The temporal expression of the expect


condition failed.

Once activated, a check/expect can reach the finished or failed state a maximum of once. Multiple
finishes and failures for a single attempt are not counted or reported.

Example 2

Limitation: Counting for expect Members

For expect members, the counter is incremented only once at the same time for the same struct instance,
so the checked counter will be higher than the sum of the failed and finished counters.
In the following example, the checked counter for v1.ex will be incremented twiceat times 1 and
3but the finish counter will be incremented only once.
unit verifier {
expect ex is @a => {[..5] ; @b} @clk;
verify() @clk is {
wait[1];
emit a; // Time 1
wait[2];
emit a; // Time 3
wait[2];
emit b; // Time 5
};
};
extend sys {
v1 : verifier is instance;
};

Specman e Language Reference


1999-2015

814

Product Version 15.1


All Rights Reserved.

If the event at time 3 was emit b, the checked counter for v1.ex would be incremented once at time 1,
and the finished counter would be incremented once.

Example 3

Counting for expects Defined in Structs

In the following example, no per-instance models are created, because the expect is defined inside a
struct. The only item in the coverage model is ip_packet.in_reset. At the end of the run, both its checked
counter and its passed counter will be two.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

struct packet {
expect in_reset is @...;
reset() @clk is {
... // Time-consuming method
};
};
struct atm_packet like packet {
};
struct atm_big_packet like atm_packet {
};
struct ip_packet like packet {
};
unit verifier {
verify() is {
var p : packet;
p = new atm_packet;
p.reset();
p = new ip_packet;
p.reset();
};
};

16.7.3

Model for check that Actions

Each check that action creates an item in the coverage model. If the action is defined inside a unit, there
will be an item for the action in the instances of this unit, in the per-instance model.

Example 4

check that Actions in Coverage Model

In the following example, the coverage model will include per-type and per-instance items as noted in
the comments:
1 unit verifier {
2
verify() is
Specman e Language Reference
1999-2015

815
.

Product Version 15.1


All Rights Reserved.

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

...
// Line 8 creates the following items:
//
Per-type: verifier.verifier_check_0
//
Per-instance: sys.v1.verify_check_0 for sys.v1
//
Per-instance: sys.v2.verify_check_0 for sys.v2
check that x > 7;
// Line 14 creates the following items:
//
Per-type: verifier.y_pos
//
Per-instance: sys.v1.y_pos for sys.v1
//
Per-instance: sys.v2.y_pos for sys.v2
check y_pos that y > 0;
};
};
struct packet {
...
send() is {
// Per-type: packet.packet_check_1
check that addr > 0;
// Per-type: packet.checksum_valid
check checksum_valid that is_valid(checksum);
};
};
extend sys {
v1 : verifier is instance;
v2 : verifier is instance;
};

16.7.4

Model for expect Members

For each expect struct member, the per-type coverage model will contain an item for the declaring
struct, whether the expect is refined in later layers or not.
If the expect is a unit member, each of the corresponding unit instances will contain an item for the
expect.

Example 5

expect Members in Structs

In the following example, the expect is defined inside a struct, so no items will appear in the
per-instance model. The model will include only one item, packet.ex1.
1 struct packet {
2
expect ex1 is @...;
3 };

Specman e Language Reference


1999-2015

816

Product Version 15.1


All Rights Reserved.

4
5
6
7
8
9
10
11
12

struct atm_packet like packet {


expect ex1 is @...; // Redefines ex1
};
struct atm_big_packet like atm_packet {
};
struct ip_packet like packet {

13 };

Example 6

expect Members in Units

In the following example, the model will include:

Per-type items:

Line 2verifier.ex1

Line 3verifier.verifier_expect_1

Line 8atm_verifier.atm_ex1

Per-instance items:

sys.v1.ex1

sys.v1.verifier_expect_1

sys.v2.ex1

sys.v2.verifier_expect_1

sys.v3.ex1

sys.v3.verifier_expect_1

sys.v3.atm_ex1

1
2
3
4
5
6
7
8
9
10
11
12

unit verifier {
expect ex1 is @...;
expect @...;
};
unit atm_verifier like verifier {
expect ex1 is @...; // Redefines ex1
expect atm_ex1 is @...; // New expect
};
extend sys {
v1 : verifier is instance;

Specman e Language Reference


1999-2015

817
.

Product Version 15.1


All Rights Reserved.

13
v2 : verifier is instance;
14
v3 : atm_verifier is instance;
15 };

16.8 Coverage API Methods


This section contains descriptions of the following predefined methods:

scan_cover() on page 818

start_group() on page 820

start_instance() on page 821

start_item() on page 822

scan_bucket() on page 823

end_item() on page 824

end_instance() on page 825

end_group() on page 827

covers.sample_cg() on page 828

See Also

Defining Coverage for Real Numbers in Managing Coverage for e Testbenches

16.8.1

scan_cover()

Purpose
Activate the Coverage API and specify items to cover

Category
Method

Syntax
scan_cover(entity-names: string): int;
Syntax Example
num_items = cover_info.scan_cover("cpu.inst_driven.*");

Specman e Language Reference


1999-2015

818

Product Version 15.1


All Rights Reserved.

Parameters
entity-names

A string of the form struct-name.group-name.item-name, where group-name is:


event-name[(instance-name)]
and where instance-name is one of the following:
per_type
item-name == bucket-name (for item instance sub-groups)
e-path-exp (for cover group instances)
and where e-path-exp has the following form:

e_path==sys.unit-inst[....][.struct-inst]
Note

Wildcards are allowed.

Description
The scan_cover() method initiates the coverage data-scanning process. It goes through all the items in
all the groups specified in the item-names parameter in the order that groups and items have been
defined.
For each group, scan_cover() calls start_group(). For each instance in the group, scan_cover() calls
start_instance() . For each item in the current instance, scan_cover() calls start_item(). Then for each
bucket of the item, it calls scan_bucket(). After all of the buckets of the item have been processed, it
calls end_item(). After all items of the instance have been processed, it calls end_instance(). After all
instances in the group have been processed, it calls end_group().
Before each call to any of the above methods, the relevant fields in the user_cover_struct are updated
to reflect the current item (and also the current bucket for scan_bucket()).
The scan_cover() method returns the number of coverage items actually scanned.

Note
The scan_cover() method cannot be extended. The methods called by scan_cover() start_group()),
start_instance(), start_item(), scan_bucket(), end_item(), end_instance() and end_group() are
initially empty and are meant to be extended.

Example
<'
struct simple_cover_struct like user_cover_struct {
};
extend sys {
Specman e Language Reference
1999-2015

819
.

Product Version 15.1


All Rights Reserved.

!cover_info: simple_cover_struct;
simple_cover_report() is {
var num_items: int;
num_items = cover_info.scan_cover("cpu.inst_driven.*");
};
};
'>

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

16.8.2

start_group()

Purpose
Process coverage group information according to user preferences

Category
Method

Syntax
start_group();
Syntax Example
start_group() is {
if group_text != NULL {out("Description: ", group_text)};
};

Description
When the scan_cover() method initiates the coverage data scanning process for a group, it updates the
group-related fields within the containing user_cover_struct and then calls the start_group() method.
The start_group() method is called for every group to be processed by scan_cover(). For every instance
within a group, scan_cover() calls the start_instance() method.
The start_group() method is originally empty. It is meant to be extended to process group data
according to user preferences.

Specman e Language Reference


1999-2015

820

Product Version 15.1


All Rights Reserved.

Note
start_group(), start_instance() and scan_cover() are all methods of the user_cover_struct.

Example
<'
struct simple_cover_struct like user_cover_struct {
start_group() is {
if group_text != NULL {out("Description: ", group_text)};
};
};
'>

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

16.8.3

start_instance()

Purpose
Process coverage instance information according to user preferences.

Category
Method

Syntax
start_instance();
Syntax Example
start_instance() is {
if instance_text != NULL {out("Description: ", instance_text)};
};

Description
When the scan_cover() method initiates the coverage data scanning process for an instance, it updates
the instance-related fields within the containing user_cover_struct and then calls the start_instance()
method. The start_instance() method is called for every instance to be processed by scan_cover().
Specman e Language Reference
1999-2015

821
.

Product Version 15.1


All Rights Reserved.

The start_instance() method is originally empty. It is meant to be extended to process instance data
according to user preferences.

Note
start_instance() and scan_cover() are methods of the user_cover_struct.

Example
<'
struct simple_show_cover_struct like user_cover_struct {
start_instance() is {
out("instance ", struct_name, ".", group_name, ".",
instance_name, ":");
if instance_text != NULL {out("Description: ", instance_text)};
};
};
'>

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

16.8.4

start_item()

Purpose
Process coverage item information according to user preferences

Category
Method

Syntax
start_item();
Syntax Example
start_item() is {
if item_text != NULL {out("Description: ", item_text)};
};

Specman e Language Reference


1999-2015

822

Product Version 15.1


All Rights Reserved.

Description
When the scan_cover() method initiates the coverage data scanning process for an item, it updates the
item-related fields within the containing user_cover_struct and then calls the start_item() method. The
start_item() method is called for every item to be processed by scan_cover().
The start_item() method is originally empty. It is meant to be extended to process item data according
to user preferences.

Note
start_item() and scan_cover() are methods of the user_cover_struct.

Example
<'
struct simple_show_cover_struct like user_cover_struct {
start_item() is {
out("item ", struct_name, ".", group_name, ".",
item_name, ":");
if item_text != NULL {out("Description: ", item_text)};
};
};
'>

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

16.8.5

scan_bucket()

Purpose
Process coverage item information according to user preferences

Category
Method

Syntax
scan_bucket();
Specman e Language Reference
1999-2015

823
.

Product Version 15.1


All Rights Reserved.

Syntax Example
scan_bucket() is {
out(count, " ", percent, "% ", bucket_name);
};

Description
When the scan_cover() method processes coverage data, then for every bucket of the item it updates the
bucket-related fields within the containing user_cover_struct and calls scan_bucket().
The scan_bucket() method is originally empty. It is meant to be extended to process bucket data
according to user preferences.

Note
scan_bucket() and scan_cover() are methods of the user_cover_struct.

Example
<'
struct simple_show_cover_struct like user_cover_struct {
scan_bucket() is {
out(str_repeat("
", cross_level), count, " - ",
percent, "% - ", status, " - ", bucket_name);
};
};
'>

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

16.8.6

end_item()

Purpose
Report end of item coverage information according to user preferences

Category
Method

Specman e Language Reference


1999-2015

824

Product Version 15.1


All Rights Reserved.

Syntax
end_item();
Syntax Example
end_item() is {
out("finished item ", item_name, "\n");
};

Description
When the scan_cover() method completes the processing of coverage data for an item, it calls the
end_item() method to report the end of item information according to user preferences.
When all items in the current group have been processed, scan_cover() calls the start_instance()
method for the next instance.
The end_item() method is originally empty. It is meant to be extended so as to process item data
according to user preferences.

Note
end_item(), start_instance() and scan_cover() are all methods of the user_cover_struct.

Example
<'
struct simple_show_cover_struct like user_cover_struct {
end_item() is {
out("end of item ", item_name, "\n");
};
};
'>

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

16.8.7

end_instance()

Purpose
Process end of instance coverage information according to user preferences.
Specman e Language Reference
1999-2015

825
.

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
end_instance();
Syntax Example
end_instance() is {
out("finished instance ", instance_name, "\n");
};

Description
When the scan_cover() method completes the processing of coverage data for an instance, it calls the
end_instance() method to report the end of instance information according to user preferences.
When all instances in the current group have been processed, scan_cover() calls the start_group()
method for the next group.
The end_instance() method is originally empty. It is meant to be extended so as to process instance data
according to user preferences.

Note
end_instance(), start_group() and scan_cover() are all methods of the user_cover_struct.

Example
<'
struct simple_show_cover_struct like user_cover_struct {
end_instance() is {
out("end of instance ", instance_name, "\n");
};
};
'>

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

Specman e Language Reference


1999-2015

826

Product Version 15.1


All Rights Reserved.

16.8.8

end_group()

Purpose
Report end of group coverage information according to user preferences

Category
Method

Syntax
end_group();
Syntax Example
end_group() is {
out("finished group", group_name, "\n");
};

Description
When the scan_cover() method completes the processing of coverage data for a group, it calls the
end_group() method to report the end of group information according to user preferences.
The end_group() method is originally empty. It is meant to be extended so as to process item data
according to user preferences.

Note
end_group() and scan_cover() are both methods of the user_cover_struct.

Example
<'
struct simple_show_cover_struct like user_cover_struct {
end_group() is {
out("end of group", group_name, "\n");
};
};
'>

Specman e Language Reference


1999-2015

827
.

Product Version 15.1


All Rights Reserved.

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

16.8.9

covers.sample_cg()

Purpose
Enable procedural sampling of a covergroup without emitting the sampling event

Category
Method

Syntax
covers.sample_cg(cg_name: string, inst: any_struct);
Syntax Example
gen u_proc_sampled.x;
covers.sample_cg("u.cov",u_proc_sampled);
};

Parameters
cg_name

Name of the covergroup, which is definition-type-name.sampling-event-name

inst

Reference to the instance of the definition type, which should be now sampled.

Description
Sample_cg enables procedural sampling of a covergroup, and all relevant instances of the covergroup,
without emitting the sampling event.
When this method is called, Specman retrieves the specified covergroup for sampling, and from this
point on, the sampling process is done exactly as it was done if the sampling event was emitted.
Notes

Each covergroup should be coupled to an event, even when all samplings of the covergroups are done
procedurally.

Specman e Language Reference


1999-2015

828

Product Version 15.1


All Rights Reserved.

Procedural sampling of an event is not be permitted before the post_generate test phase.

Example
<'
unit u{
x: uint(bits:2);
event cov;
cover cov using per_unit_instance is {
item x;
};
};
extend sys{
u_sampled_by_event: u is instance;
u_proc_sampled: u is instance;
run() is also{
for i from 1 to 2 {
gen u_sampled_by_event.x;
emit u_sampled_by_event.cov;
};
for i from 1 to 3 {
gen u_proc_sampled.x;
covers.sample_cg("u.cov",u_proc_sampled);
};
};
};
'>

Results of show cover *.cov* - batch command:


Specman Coverage report
=======================
Command:
show cover -kind = full *.cov*.*
Grading_formula:
linear
At least multiplier: 1
Show mode:
both
Number of tests:
1
Note:
%t is a percent from total, %p is a percent from parent

Cover group: u.cov


==================
Grade: 0.75

Weight: 1

Specman e Language Reference


1999-2015

829
.

Product Version 15.1


All Rights Reserved.

** x **
Samples: 5

Tests: 1

Grade: 0.75

Weight: 1

grade
goal
samples tests
%t
x
-----------------------------------------------0.00
1
0
0
0
0
1.00
1
2
1
40
1
1.00
1
2
1
40
2
1.00
1
1
1
20
3

Cover group: u.cov(e_path==sys.u_sampled_by_event)


==================================================
Grade: 0.50
** x **
Samples: 2

Weight: 1

Tests: 1

Grade: 0.50

Weight: 1

grade
goal
samples tests
%t
x
-----------------------------------------------0.00
1
0
0
0
0
1.00
1
1
1
50
1
0.00
1
0
0
0
2
1.00
1
1
1
50
3

Cover group: u.cov(e_path==sys.u_proc_sampled)


==============================================
Grade: 0.50
** x **
Samples: 3

Weight: 1

Tests: 1

Grade: 0.50

Weight: 1

grade
goal
samples tests
%t
x
-----------------------------------------------0.00
1
0
0
0
0
1.00
1
1
1
33
1
1.00
1
2
1
67
2
0.00
1
0
0
0
3

Specman e Language Reference


1999-2015

830

Product Version 15.1


All Rights Reserved.

See Also

Customizing Coverage Data Collection in Managing Coverage for e Testbenches

Specman e Language Reference


1999-2015

831
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

832

Product Version 15.1


All Rights Reserved.

17

Simulation-Related Constructs

This chapter contains the following sections:

Verilog and VHDL Stubs Files and Units on page 833

Verilog Statements or Unit Members on page 834

VHDL Statements and Unit Members on page 860

Simulation-Related Actions on page 886

Simulation-Related Expressions on page 897

Simulation-Related Routines on page 900

See Also

Simulation-Related Methods on page 1272

17.1 Verilog and VHDL Stubs Files and Units


When your e code contains units, it is recommended to use verilog or vhdl unit members rather than the
equivalent verilog or vhdl statements. verilog or vhdl unit members increase the modularity of your
design because you can use relative path names rather than absolute path names to identify the HDL
objects you intend to access from e. Specman is able to resolve the relative path names because you bind
an e unit instance to a particular component in the DUT hierarchy.
Also, for verilog or vhdl unit members, any non-constant expressions are calculated within the context
of the unit instance. For verilog or vhdl statements, any non-constant expressions are calculated within
the context of sys.

Specman e Language Reference


1999-2015

833
.

Product Version 15.1


All Rights Reserved.

Before creating a stubs file, Specman performs generation to create a unit instance tree. Specman uses
the unit instance tree to resolve any relative HDL paths used in the verilog or vhdl unit members. The
stubs file contains a separate section for each unit instance that has verilog or vhdl unit members.
Relative HDL paths are automatically converted to absolute paths in the stubs file and expressions in
HDL declarations are replaced with their values.
If you create an HDL stubs file and then add or modify a verilog statement or unit member or a vhdl
code, vhdl function, or vhdl procedure statement or unit member, you must recreate the VHDL stub
file in order to avoid a stubs file mismatch error. (See write stubs Specman Command Reference for a
complete description of how Specman compares the stubs file to the currently loaded or compiled e
code.) If you are using units and you modify the tree of unit instances by adding, deleting, or changing
the HDL path of an instance that contains a vhdl or verilog unit member, you must rewrite the VHDL
stub file.
All verilog or vhdl statements are allowed as unit members, with the following restrictions:

verilog | vhdl time declarations can only be used as statements. They cannot be used as unit members
because the time resolution setting must be the same for all units.
verilog import declarations can only be used as statements.
vhdl driver declarations can only be used as unit members. They cannot be used as statements
because they influence only assignments made by methods of the enclosing unit or of the structs
enclosed by this unit.

See Also

Verilog Statements or Unit Members on page 834

VHDL Statements and Unit Members on page 860

If You Are Using Tick Access with the Simplified Setup in Simplified Port Requirements for Incisive
Simulator in Creating e Testbenches

17.2 Verilog Statements or Unit Members


Some basic functionality of the Verilog simulator interface, such as setting or sampling the values of
some Verilog objects, is enabled without any action on your part. However, some features, such as the
continuous driving of Verilog signals or calling of Verilog tasks and functions, requires some
user-specified declarationsverilog statements or unit members. The following sections describe these
constructs:

verilog code on page 835

verilog function on page 837

verilog import on page 840

verilog task on page 844

Specman e Language Reference


1999-2015

834

Product Version 15.1


All Rights Reserved.

verilog time on page 847

verilog variable reg | wire on page 849

verilog variable memory on page 858

17.2.1

verilog code

Purpose
Write Verilog code directly to the stubs file

Category
Statement or unit member

Syntax
verilog code {list-of-strings}
Syntax examples:
verilog code {"initial clk = 1'b1;"};
unit router {
verilog code { "initial "; s};
verilog code ls;
};

Parameters
list-of-strings Any list of strings that after concatenation creates any sequence of legal Verilog
code. Specman does not check for Verilog syntax errors. Verilog syntax errors are
identified only when you compile or interpret the file with the Verilog compiler.
The curly braces are required only if the list of strings contains more than one string.

Description
Specifies a list of Verilog strings to be included in the Verilog stubs file each time it is generated. The
stubs file contains code that enables some Verilog-related features. It is recommended to use verilog
code statements or unit members to modify this file rather than to modify it by hand.

Specman e Language Reference


1999-2015

835
.

Product Version 15.1


All Rights Reserved.

Notes

verilog code unit members or statements are ignored in mixed language designs if the agent of the
unit (for unit members) or of sys (for statements) is defined as anything other than a Verilog agent.
When verilog code is used as a unit member, any non-constant expressions in the list of strings are
calculated within the context of a unit instance. Each unit instance adds a separate fragment of Verilog
code to the stubs file. When used as a statement, any non-constant expressions in the list of strings
are calculated within the context of sys.
Whenever you add or modify a verilog code statement or unit member or add an instance of a unit
containing a verilog code unit member, you must create a new stubs file. See When to Regenerate
the Stubs Files in Specman Command Reference for more information.

Example 1
This example uses a verilog code statement to define a Verilog event, clk_rise, in the stubs file. The
Verilog clk_rise event is triggered on every positive edge of the HDL signal, top.clk. Deriving an e event
from the Verilog clk_rise event rather than from the HDL signal top.clk itself reduces the number of
callbacks to Specman by half.

top.v
module top();
reg clk;
initial clk = 0;
always #50 clk = ~clk;
endmodule

clk.e
verilog code {
"event clk_rise;";
"always @(posedge top.clk) begin";
" ->clk_rise;";
"end"
};
extend sys {
event clk_rise is change('specman.clk_rise')@sim;
on clk_rise {
print sys.time;
};
};

Specman e Language Reference


1999-2015

836

Product Version 15.1


All Rights Reserved.

Result (with IES-XL)


ncsim> run
sys.time
sys.time
sys.time
sys.time
sys.time
sys.time
sys.time
...

=
=
=
=
=
=
=

50
150
250
350
450
550
650

Example 2
This example initializes an HDL clock by adding code to the stubs file. It uses verilog code as a unit
member so that the clock name and its initial value can be configured on a unit instance basis.
<'
unit channel {
clk_name: string;
keep soft clk_name == "clk";
clk_init: bit;
keep soft clk_init == 1;
s: string;
keep s == append("initial ", full_hdl_path(),".",clk_name,
"= ",clk_init,";");
verilog code {s};
};
extend sys {
chan: channel is instance;
keep chan.hdl_path() == "top";
};
'>

See Also

sn or $sn or [Control-]Enter in the Specman Command Reference

write stubs in the Specman Command Reference

17.2.2

verilog function

Note See also Using e Method Ports with SystemVerilog Functions and Tasks in Specman Integrators
Guide.

Specman e Language Reference


1999-2015

837
.

Product Version 15.1


All Rights Reserved.

Purpose
Declare a Verilog function

Category
Statement or unit member

Syntax
verilog function 'HDL-pathname' (verilog-function-parameter[, ... ]): result-size-exp
Syntax examples:
verilog function 'top.write_mem'(addr:32, data:32):32;
extend my_unit {
verilog function '(read_mem_name)'(addr:addr_width):ret_size;
}

Parameters
HDL-pathname

The full path to the Verilog function. If this name is not a constant, it is
calculated after the final step of pre-run generation. See 'HDL-pathname' on
page 897 for a complete description of HDL path syntax.

verilog-functionparameter

The syntax for each parameter is parameter_name:size_exp. The parameter


name need not match the name in Verilog. All parameters are passed by
position, not name. All parameters must be inputs, and the number of
parameters must match the number declared in the Verilog function.
The size-exp must be a legal unsigned integer expression specifying the size in
bits of the parameter. No default size is assumed. If the size expression is not a
constant, it is calculated after the final step of pre-run generation.
Note You can pass only numeric scalars or lists of numeric scalars. To pass
a string, for example, you must convert the string to a list of byte.

result-size-exp

A legal unsigned integer expression specifying the size in bits of the returned
value. No default size is assumed. If the size expression is not a constant, it is
calculated after the final step of pre-run generation.

Specman e Language Reference


1999-2015

838

Product Version 15.1


All Rights Reserved.

Description
Declares a Verilog function in e so that it can be called from a time-consuming method (TCM).
When verilog function is used as a unit member, any non-constant expressions in the list of strings are
calculated within the context of a unit instance. Each unit instance adds a separate fragment of Verilog
code to the stubs file. When used as a statement, any non-constant expressions in the list of strings are
calculated within the context of sys.

Notes

Calls to Verilog functions are value-returning expressions.


Even though Verilog functions do not consume time in Verilog, they do so on the Specman side
because they require a context switch between Specman and the simulator. Thus, Verilog functions
can be called only from TCMs.
Specman does not support concurrent calls to a Verilog function. In other words, you cannot call the
same Verilog function from more than one thread in the same Specman tick.
You must explicitly pack all structs before passing them in as inputs to the function.
Whenever you add or modify a verilog function statement or unit member or add an instance of a
unit containing a verilog function unit member, you must create a new stubs file and then load the
file into the Verilog simulator. See When to Regenerate the Stubs Files in Specman Command
Reference for more information.
You can also use e method ports to access Verilog functions via the SystemVerilog DPI. To do so,
enter the irun -snsv switch when you start simulation to ensure the SystemVerilog DPI is available.
For more information about using method ports, see Using e Method Ports with SystemVerilog
Functions and Tasks in Specman Integrators Guide.

Example
The following function has two 32-bit inputs and returns a 32-bit error status. The memory_driver unit
calls the top.write_mem() function.
unit memory_driver {
addr_width: uint;
keep soft addr_width == 32;
data_width: uint;
keep soft data_width == 32;
verilog function 'top.write_mem'(addr:addr_width,data:data_width):32;
event mem_enable is rise ('top.enable') @sim;
write() @mem_enable is {
var error_status: int;
error_status = 'top.write_mem'(31,45);
Specman e Language Reference
1999-2015

839
.

Product Version 15.1


All Rights Reserved.

};
};

See Also

'HDL-pathname' on page 897

show functions in the Specman Command Reference

write stubs in the Specman Command Reference

Rules for Extending Methods in Creating e Testbenches

17.2.3

verilog import

Purpose
Read in Verilog text macros

Category
Statement

Syntax
verilog import file-name
Syntax Example
verilog import defines_MCP.v;

Parameters
file-name

Specman searches for imported files in the directories specified in


$SPECMAN_PATH. If the file is not found in $SPECMAN_PATH, Specman then
searches the directory where the importing file resides.

Description
Reads in a file that includes Verilog `define text macros. After reading in the file, you can use these text
macros in Specman expressions.
Specman understands several Verilog language constructs when reading the `define macros:

Specman e Language Reference


1999-2015

840

Product Version 15.1


All Rights Reserved.

It recognizes the Verilog `include directive and reads in the specified file.
It recognizes the Verilog `ifdef, `else, and `endif directives and skips the irrelevant parts of the file
according to the currently defined symbols.

Notes

verilog import statements cannot be used as unit members.


verilog import statements must appear in the e file before any other statement except package,
define, and import statements. package statements must appear first in the file.
Whenever you add or redefine an imported Verilog macro that appears in an HDL declaration, you
need to create a new stubs file and then load the file into the simulator. For example, if you use a
Verilog macro to specify the width of the parameters in a task identified with verilog task, then you
need to recreate the stubs file if the macro is redefined. See When to Regenerate the Stubs Files in
Specman Command Reference for more information.

Example 1
To import more than one file, you must use multiple verilog import statements or use the Verilog
compiler directive `include. You can import the same file more than once. If you define the same macro
with different values before using it, Specman uses the definition that is loaded last. Once you use the
macro, however, you cannot redefine it. Subsequent definitions are ignored without warning.
The following example shows how to import multiple files. Note that once X is used in the x.e file, its
value of 7 (the last loaded definition before it is used) cannot be changed.

a.v
define X 5

b.v
define X 7

x.e
verilog import a.v ;
verilog import b.v ;
extend sys {
run() is also {
print X;
};
};

Specman e Language Reference


1999-2015

841
.

Product Version 15.1


All Rights Reserved.

y.e
verilog import a.v ;
extend sys {
run() is also {
print X;
};
};

z.e
verilog import b.v ;

Result
Specman > load x.e
Reading Verilog a.v (imported by x.e) ...
Read 1 defines (+0 deferred defines) from a.v
Reading Verilog b.v (imported by x.e) ...
Loading x.e ...
read...parse...update...patch...h code...code...clean...
Specman x> show defines
Currently verilog defined symbols =
Index Name
Value
Type
--------------------------------------------------------------0
'X
7
Specman x> load y.e
Loading y.e ...
read...parse...update...patch...h code...code...clean...
Specman y> show defines
Currently verilog defined symbols =
Index Name
Value
Type
--------------------------------------------------------------0
'X
7
Specman y> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
7 = 7
7 = 7
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.
Specman y> load z.e
Specman e Language Reference
1999-2015

842

Product Version 15.1


All Rights Reserved.

Loading z.e ...


read...parse...update...patch...h code...code...clean...
Specman z> show defines
Currently verilog defined symbols =
Index Name
Value
Type
--------------------------------------------------------------0
'X
7
Specman z> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
7 = 7
7 = 7
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.
Specman z> quit

Example 2
You can use Verilog macros everywhere a Specman macro is allowed. For example, you can use Verilog
macros in width declarations or when assigning values to enumerated items.

macros.v
define BASIC_DELAY
2
ifdef OLD_TECH
define TRANS_DELAY
'BASIC_DELAY+3
else
define TRANS_DELAY
`BASIC_DELAY
endif
define TOP
tb
define READY `TOP.ready
define WORD_WIDTH 8
define HIGH_BIT
7

dut_driver.e
verilog import macros.v;
extend sys {
event pclk;
driver: dut_driver;
event pclk is only @any; -- for stand-alone mode
};
Specman e Language Reference
1999-2015

843
.

Product Version 15.1


All Rights Reserved.

struct dut_driver {
ld: list of int(bits: `WORD_WIDTH);
keep ld.size() in [1..30];
stimuli() @sys.pclk is {
'`READY' = 1;
for each in ld {
wait until true('`READY' == 1);
'`TOP.data_in' = it;
wait [`TRANS_DELAY];
};
stop_run();
};
run() is also {
start stimuli();
};
};

See Also

Using Verilog Defines in the Specman Integrators Guide

specman deferred on page 899

show defines in the Specman Command Reference

Environment Variables Used with Specman in the Specman Configuration Guide

17.2.4

verilog task

Note See also Using e Method Ports with SystemVerilog Functions and Tasks in Specman Integrators
Guide.

Purpose
Declare a Verilog task

Category
Statement or unit member

Syntax
verilog task 'HDL-pathname' (verilog-task-parameter[, ...])
Specman e Language Reference
1999-2015

844

Product Version 15.1


All Rights Reserved.

Syntax examples:
verilog task 'top.read'(addr: 64, cell: 128:out);
verilog task 'top.(read_task_name)'(addr:addr_width, cell:cell_width:out);

Parameters
HDL-pathname

The full path to the Verilog task. If this name is not a constant, it is
calculated after the final step of pre-run generation. See
'HDL-pathname' on page 897 for a complete description of HDL
path syntax.

verilog-task-parameter

The verilog-task-parameter has the syntax name:size-exp[:direction].


The name need not match the name in Verilog. All parameters are
passed by position, not name. The number of parameters must match
the number of parameters in the task declaration in Verilog.
The size-exp must be a legal unsigned integer expression specifying
the size in bits of the parameter. No default size is assumed. If the size
expression is not a constant, it is calculated after the final step of
pre-run generation.
The direction is one of the following keywords: input (or in), output
(or out), inout. The default is input.
Note You can pass only numeric scalars or lists of numeric scalars.
To pass a string, for example, you must convert the string to a list of
byte.

Description
Declares a Verilog user-defined task or system task in e so that it can be called from a TCM. In the
following example, addr is a 64-bit input and cell is a 128-bit output. $display is a Verilog system
task.
verilog task 'top.read'(addr: 64, cell: 128:out);
verilog task '$display'(int:32);

Notes

Calls to Verilog tasks are time-consuming actions and can only be made from TCMs.
Specman does not support concurrent calls to a Verilog task. In other words, you cannot call the same
Verilog task from multiple threads in the same Specman tick.

Specman e Language Reference


1999-2015

845
.

Product Version 15.1


All Rights Reserved.

You must explicitly pack all structs before passing them in as inputs to the task.
When verilog task is used as a unit member, any non-constant expressions in the list of strings are
calculated within the context of a unit instance. Each unit instance adds a separate fragment of Verilog
code to the stubs file. When used as a statement, any non-constant expressions in the list of strings
are calculated within the context of sys.
Whenever you add or modify a verilog task statement or unit member or add an instance of a unit
containing a verilog task unit member, you must create a new stubs file and then load the file into
the Verilog simulator. See When to Regenerate the Stubs Files in Specman Command Reference for
more information.
You can also use e method ports to access Verilog tasks via the SystemVerilog DPI. To do so, enter
the irun -snsv switch when you start simulation to ensure the SystemVerilog DPI is available. For
more information about using method ports, see Using e Method Ports with SystemVerilog Functions
and Tasks in Specman Integrators Guide.

Example
This task is similar to the Verilog function write_mem shown in the example for the verilog function
unit member (verilog function on page 837). This task returns an error status as an output parameter.
struct mem_w {
addr: int;
data: int(bits: 64);
};
unit receiver {
read_task_name: string;
addr_width: uint;
keep soft addr_width == 32;
data_width: uint;
keep soft data_width == 64;
verilog task 'top.(read_task_name)'
(addr:addr_width:in,data:data_width:out,status:32:out);
event mem_read_enable;
get_mem(mw: mem_w) @mem_read_enable is {
var error_status: int;
'top.(read_task_name)'(mw.addr, mw.data, error_status);
assert error_status == 0;
};
};

Specman e Language Reference


1999-2015

846

Product Version 15.1


All Rights Reserved.

See Also

'HDL-pathname' on page 897

show tasks in the Specman Command Reference

write stubs in the Specman Command Reference

Rules for Extending Methods in Creating e Testbenches

17.2.5

verilog time

Purpose
Set the Verilog time resolution

Category
Statement

Syntax
verilog time verilog-time-scale
Syntax examples:
verilog time 100ns/10ns;
verilog time num1 ns/num2 ns;

Parameters
verilog-time-scale

The Verilog specification for timescale has the syntax time-exp unit / precision-exp
unit.
time-exp and precision-exp must be integer expressions. If the expression is not a
constant, it is calculated after the final step of pre-run generation. According to
Verilog standards, the legal values for the integer expressions are 1, 10 and 100,
but Specman does not check whether the value is legal or not.
unit is any unit of time measurement. According to Verilog standards, the valid
character strings are s, ms, us, ns, ps, and fs, but Specman does not check whether
the value is legal or not.

Specman e Language Reference


1999-2015

847
.

Product Version 15.1


All Rights Reserved.

Description
Sets the time resolution in the Verilog stubs file to the specified verilog-time-scale.
If you do not use the verilog time statement, Specman uses the timescale from the simulator side.
Specman uses the verilog time statement to scale the following:

# delays in verilog variable or verilog code statements

delays in Specman temporal expressions

simulation time as shown in sys.time and sys.realtime, a 64-bit integer field that stores Specman time.

The precision of the timescale scales the precision of sys.realtime.

Notes

When the DUT contains more than one `timescale directive, using the verilog time statement is
strongly recommended. Otherwise, Specman time becomes dependent on the order of the Verilog
modules.
If you need to call Specman (using $sn) from Verilog code explicitly, use the verilog code statement
to put the Specman call in the stubs file. This ensures that the call to Specman has the timescale
shown in the stubs file instead of a timescale from other parts of the Verilog code.
The Verilog timescale precision in the verilog time statement must be set to the precision required
for # delays in verilog variable or verilog code statements.
verilog time statements cannot be used as unit members.
If you use a non-constant expression for the time or the precision, this expression is computed in the
context of sys and so must be visible in that context.
Whenever you add or modify a verilog time statement in an e module, you must create a new stubs
file and then load the file into the Verilog simulator. See When to Regenerate the Stubs Files in
Specman Command Reference for more information.

Example 1
verilog time 10ns/1ns;

Example 2
verilog time (num1)ns/(num2)ns;
extend sys {
num1:int;
num2:int;
keep num1 == 100;
Specman e Language Reference
1999-2015

848

Product Version 15.1


All Rights Reserved.

keep num2 == 10;


};

See Also

sn or $sn or [Control-]Enter in the Specman Command Reference

write stubs in the Specman Command Reference

17.2.6
Note

verilog variable reg | wire

See also the use of e ports to access Verilog/SystemVerilog registers and wires as described in

Integrating the e Testbence with Verilog and Integrating the e Testbence with SystemVerilog in Specman

Integrators Guide.

Purpose
Identify a Verilog register or wire. Provide automatic access for a Verilog register or wire during
simulation.

Category
Statement or unit member

Syntax
verilog variable 'HDL-pathname' [using option, ...]
Syntax examples:
verilog variable 'top.dbus[5:0]' using wire,drive="@(posedge top.m)";
verilog variable 'i1.(reset_name)[m:l]' using wire,drive_hold=dh_opt;

Specman e Language Reference


1999-2015

849
.

Product Version 15.1


All Rights Reserved.

Parameters
HDL-pathname

The complete path to the Verilog object, a register or a net. If this name is
not a constantthat is, if it is a computed nameit is calculated after the
final step of pre-run generation. See 'HDL-pathname' on page 897 for a
complete description of HDL path syntax.
Note If the register or wire has a width greater than 1, the bit range must
be explicitly declared in order to create internal temporary registers of the
correct width.
The width range has the syntax
[left-bound-exp:right-bound-exp]
Where left-bound-exp and right-bound-exp are any legal integer
expressions. The width range must be the same (including the descending
or ascending order) as in the Verilog declaration. If these expressions are
not constants, they are calculated after the final step of pre-run generation.

option

A list of one or more of the following options separated by commas.

delta_delay=bool

For external input simple ports, when TRUE this option requires Specman
to sample the old value of the appropriate Verilog signal, as it was one
simulator schedulers iteration before the change. The default is FALSE

drive=string-exp

Specifies that the Verilog object is driven when the event specified by
string-exp occurs. string-exp is any legal string expression specifying a
legal Verilog timing control. If this expression is not a constant, it is
calculated after the final step of pre-run generation.
Note When you force an HDL object, the value is applied immediately,
without a delay, even if a drive delay has been specified for the object.

drive_hold=string-exp

Specman e Language Reference


1999-2015

Specifies a Verilog event after which the HDL objects value is set to z.
string-exp is any legal string expression specifying a legal Verilog timing
control. If this expression is not a constant, it is calculated after the final
step of pre-run generation. The drive_hold option requires that you also
specify the drive option.

850

Product Version 15.1


All Rights Reserved.

net,

Specifies that the Verilog object is a net (wire).

wire

Incisive requires this option only when you drive from within the model as
well as from e and you want the Verilog wire to be resolved. However, in a
future release, IES-XL might require this option any time you drive a
Verilog wire from e. For more information, see the description of
DEPR_VERILOG_WIRE_UNDEFINED in Deprecated Features and
Constructs in the Specman Deprecation and Backwards Compatability.
Third party simulators require this option anytime you drive a Verilog wire
from e.
If not used, no resolution is done. Specman simply deposits a value on
the wire at the end of the time-step, overwriting values driven by the
simulator at that time. Deposited values can be changed by the simulator at
the next simulation time-step.

forcible

Allows forcing of Verilog wires. By default Verilog wires are not forcible.
This option requires that you also specify the net or wire option.

strobe=string-exp

Specifies that the value of the Verilog object is sampled at the event
specified using string-exp. string-exp is any legal string expression
specifying a legal Verilog timing control. If this expression is not a
constant, it is calculated after the final step of pre-run generation.

Description
Allows access in Specman to the Verilog object named in 'HDL-pathname', a register or a net. In
general, you can access Verilog objects using the 'HDL-pathname' expression. The verilog variable
statement is necessary when you need to:

Provide automatic access during simulation to HDL objects that are referenced with computed names.

Drive or force a wire.

Drive or sample a wire or reg with an offset from the Specman callback.

By default the value driven by Specman is always driven last, overwriting all values driven by Verilog.
If you do not include a verilog variable statement when one is required, you receive an error message.
verilog variable declarations for the same object can be repeated (to allow incremental building of e
code), but each repeated declaration must be identical.

Specman e Language Reference


1999-2015

851
.

Product Version 15.1


All Rights Reserved.

Notes

Assignments to Verilog nets are not propagated until the start of simulation, so no pre-run initialization
of Verilog nets can be performed by Specman.
verilog variable statements are considered extensions of sys. Accordingly, any non-constant
expressions cannot use variables that are not visible within sys. For verilog variable unit members,
any non-constant expressions are calculated within the context of a unit instance.
Whenever you add or modify a verilog variable statement or unit member or add an instance of a
unit containing a verilog variable unit member, you must create a new stubs file and then load the
file into the Verilog simulator. See When to Regenerate the Stubs Files in Specman Command
Reference for more information.
Note

This requirement does not apply if you are running IES-XL with irun.

Example 1
In the following example, the verilog variable unit member ensures automatic access to the Verilog clk
signal during simulation. This access is required because the tick notation for accessing clk depends on
a computed name ((my_clk)). Specman evaluates the computed name after compilation, which is too
late to provide access to this signal during simulation.
Note If you deleted the verilog variable declaration from this example, you would have to provide
access via an access file or the +access option during an IES-XL simulation. Using the +access option
can significantly degrade simulation performance.
Note that this use of verilog variable does not require the using option.
'unit verify {
...
my_clk: string;
keep my_clk == "~/tb/clk";
verilog variable '~/tb/clk';
event clk_rise is change('(my_clk)') @sim;
...
};
'

Example 2
The following example sets drive and drive_hold timing controls on a register:
verilog variable 'top.reset_request' using
drive="#5",drive_hold="@(negedge clock)";
struct controller {
event reset_request;

Specman e Language Reference


1999-2015

852

Product Version 15.1


All Rights Reserved.

on reset_request {
'top.reset_request' = 1;
};
};

If, for example, the Specman event reset_request is emitted at time 100ns, then the Verilog top-level
register reset_request is set at time 105ns, and it is disconnected (assigned Z value) at the next
negative edge of the clock.

Example 3
The following example sets strobe and drive delays for a wire using a verilog variable unit member
and a non-constant expression.
unit box {
bus_name: string;
bus_width: uint;
strobe_option: string;
drive_option: string;
drive_hold_option: string;
verilog variable '(bus_name)[bus_width-1:0]' using
strobe=strobe_option,
drive=drive_option,
drive_hold=drive_hold_option,
wire;
};
extend sys {
box: box is instance;
keep box.hdl_path() == "top_box";
keep box.bus_name == "xx_bus";
keep box.bus_width == 64;
keep box.strobe_option == "@(posedge top.clk_b)";
keep box.drive_option == "@(negedge top.clk_b) #3";
keep box.drive_hold_option == "@(negedge top.clk_b) #10";
};

The verilog variable ... using strobe statement creates an additional temporary variable in the Verilog
stubs file that strobes the value of the real Verilog object, according to the timing conditions specified for
this option. Any read operation of the real Verilog object in e code accesses the temporary variable and
thus gets the latest strobed value. In this example, an additional register, top__xx_bus, is created and
this register gets the current value of top.xx_bus[63:0] at every positive edge on top.clk_b.

Example 4
Here is a complete example of how to drive a clock wire from Specman.

Specman e Language Reference


1999-2015

853
.

Product Version 15.1


All Rights Reserved.

clk.e
verilog time 1ns / 1ns;
verilog variable 'top.ev_clock' using wire ;
define CLOCK_HALF_PERIOD 50;
extend sys {
dut: dut;
};
struct dut {
clk: uint (bits:1);
event dut_evclk is rise ('top.ev_clock')@sim;
driver() @sys.any is {
var drive_var: int = 1;
'top.ev_clock' = 0;
while(TRUE) {
wait delay(CLOCK_HALF_PERIOD);
'top.ev_clock' = drive_var;
drive_var = ~drive_var;
};
};
wait_and_stop() @sys.any is {
wait [100] * cycle;
stop_run();
};
run() is also {
start driver();
start wait_and_stop();
};
};

clk.v
'timescale 1 ns / 1ns
module top;
wire ev_clock ;
endmodule

Results (with IES-XL)


ncsim> probe -screen ev_clock
Specman e Language Reference
1999-2015

854

Product Version 15.1


All Rights Reserved.

ncsim> run
Time: 0 FS: top.ev_clock = 1hz
Time: 0 FS: top.ev_clock = 1h0
Time: 50 FS: top.ev_clock = 1h1
Time: 100 FS: top.ev_clock = 1h0
Time: 150 FS: top.ev_clock = 1h1
...

Example 5
This example shows how to use verilog variable as a unit member with a relative path. In this case, the
full HDL path of the unit driver is prefixed to the relative path rxd in order to access the rxd signal in
each of the DUT receivers. For example ~/top.chan0.rx.rxd accesses the rxd signal in the first
channels receiver.

enet_env.e
<'
unit enet_env {
keep hdl_path() == "~/top";
ports : list of enet_port is instance;
keep soft ports.size() == 4;
keep for each in ports {
.number == index;
.hdl_path() == append("chan", index);
};
};
unit enet_port {
number
injector
collector
keep
keep
keep
keep
keep
keep

: int;
: driver is instance;
: receiver is instance;

injector.parent_port == me;
injector.number == number;
injector.hdl_path() == "rx";
collector.parent_port == me;
collector.number == number;
collector.hdl_path() == "tx";

};
unit driver {
parent_port
number

: enet_port;
: int;

Specman e Language Reference


1999-2015

855
.

Product Version 15.1


All Rights Reserved.

event clk is rise ('~/top.clock')@sim;


verilog variable 'rxd[7:0]' using wire;// Unit member with relative path
send_data() @clk is {
out("Injecting data at ", full_hdl_path());
var pkt: packet;
gen pkt;
var total_data
: list of byte;
total_data = pack(packing.low, pkt);
print total_data;
wait cycle;
for each (data) in total_data {
'rxd' = data;
// inject data
wait cycle;
};
wait [50] * cycle;
stop_run();
};
run() is also {
start send_data();
};
};
unit receiver {
parent_port
number
};

: enet_port;
: int;

struct packet {
%data: list of byte;
};
extend sys {
enet: enet_env is instance;
};
'>

top.v
module top ();
reg clock;
initial clock = 0;
always #50 clock = ~clock;

Specman e Language Reference


1999-2015

856

Product Version 15.1


All Rights Reserved.

channel
channel
channel
channel

chan0();
chan1();
chan2();
chan3();

endmodule
module channel();
receiver rx();
transmitter tx();
endmodule
module receiver();
wire [7:0] rxd;
endmodule
module transmitter();
endmodule

Results
ncsim> run
Injecting data at ~/top.chan0.rx
total_data = (27 items, dec):
201 120 34 42 158 187
38 21 43 49 151 151

67
10

96
79

Injecting data at ~/top.chan1.rx


total_data = (12 items, dec):
70 48 246 35
78 170 156 136
Injecting data at ~/top.chan2.rx
total_data = (22 items, dec):
170 70 48 175
50 112
152 108 147 136

39 26
83 239

255 147 240


2
181 102 176 145
249 124 77

10 133

33 156

109 53 65 156
62 217 131 249

.0
.12
.24

.0

.0
.12

Injecting data at ~/top.chan3.rx


total_data = (3 items, dec):
146

71 163

.0

Last specman tick - stop_run() was called


Normal stop - stop_run() is completed
Specman e Language Reference
1999-2015

857
.

Product Version 15.1


All Rights Reserved.

Checking the test ...


ncsim> exit

See Also

'HDL-pathname' on page 897

force on page 886

release on page 892

Specman File Conventions, Search Paths, and Log Files in Compiling, Linking, and Running

Specman

If You Are Using Tick Access with the Simplified Setup in Simplified Port Requirements for Incisive
Simulator in Creating e Testbenches

For third-party simulators:

write stubs in the Specman Command Reference

17.2.7

verilog variable memory

Note See also the use of e ports to access Verilog/SystemVerilog memories as described in Accessing
Verilog Memories and Multidimensional Arrays with Indexed Ports and Using Indexed Ports wtih Complex
SystemVerilog Expressions in Specman Integrators Guide.

Purpose
Identify a Verilog memory

Category
Statement or unit member

Syntax
verilog variable 'HDL-pathname [mem-range] [verilog-reg-range]'
[using propagate_event]
Syntax Example
verilog variable 'top.my_mem[1:10000][31:0]';

Specman e Language Reference


1999-2015

858

Product Version 15.1


All Rights Reserved.

Parameters
HDL-pathname

The full path to the Verilog memory. If this name is not a constant, it is
calculated after the final step of pre-run generation. See 'HDL-pathname'
on page 897 for a complete description of HDL path syntax.

mem-range

A legal expression specifying the range of the memory elements. A legal


expression has the syntax [exp:exp]. If this expression is not a constant, it
is calculated after the final step of pre-run generation.

using propagate_event

By default, an assignment from Specman to a Verilog memory element


doesn't require the propagation event to be issued by the corresponding
simulator. This option lets you explicitly require that the propagation event
be issued. This option may slow performance and thus should be used only
when needed, for example to enable probing and debugging of the memory
element. The default is FALSE.

verilog-reg-range

A legal expression specifying the width of each memory element. A legal


expression has the syntax [exp:exp]. If this expression is not a constant, it
is calculated after the final step of pre-run generation.

Description
Allows access in Specman to a Verilog memory. verilog variable declarations for the same memory can
be repeated (to allow incremental building of e code), but each repeated declaration must be identical.
Note that the order of the range specifiers in the Specman syntax is the reverse of the Verilog declaration
order.
For example, if a memory is defined in Verilog as follows:
module top;
reg[31:0] my_mem[1:10000];
endmodule

The corresponding verilog variable statement is:


verilog variable 'top.my_mem[1:10000][31:0]';

Notes

verilog variable statements are considered extensions of sys. Accordingly, any non-constant
expressions icannot use variables that are not visible within sys. For verilog variable unit members,
any non-constant expressions are calculated within the context of a unit instance.

Specman e Language Reference


1999-2015

859
.

Product Version 15.1


All Rights Reserved.

Whenever you add or modify a verilog variable statement or unit member or add an instance of a
unit containing a verilog variable unit member, you must create a new stubs file and then load the
file into the Verilog simulator. See When to Regenerate the Stubs Files in Specman Command
Reference for more information.

Rules for Using Verilog Memories

Only a single register element from the Verilog memory can be accessed in one e expression (such
as 'top.my_mem[0]' or 'top.my_mem[j]').
Verilog memories are always accessed directly, not cached, for reading and writing. You must
organize how reading and writing memories occurs within a Specman tick.
Whenever you add or modify a verilog variable statement or unit member or add an instance of a
unit containing a verilog variable unit member, you must create a new stubs file and then load the
file into the Verilog simulator. See When to Regenerate the Stubs Files in Specman Command
Reference for more information.

See Also

'HDL-pathname' on page 897

write stubs in the Specman Command Reference

If You Are Using Tick Access with the Simplified Setup in Simplified Port Requirements for Incisive
Simulator in Creating e Testbenches

17.3 VHDL Statements and Unit Members


Some basic functionality of the VHDL simulator interface, such as setting or sampling the values of
some VHDL objects, is enabled without any action on your part. However, some features, such as the
continuous driving of VHDL signals or calling of VHDL subprograms, requires some user-specified
vhdl statements or unit members. The following sections describe these statements and unit members:

vhdl object on page 861

vhdl code on page 863

vhdl driver on page 865

vhdl function on page 872

vhdl procedure on page 876

vhdl time on page 885

Specman e Language Reference


1999-2015

860

Product Version 15.1


All Rights Reserved.

17.3.1
Note

vhdl object

See also the use of e ports to access VHDL signals as described in Integrating the e Testbench

with VHDL in Specman Integrators Guide.

Purpose
Provide automatic access for a VHDL signal.

Category
Unit member or statement

Syntax
vhdl object 'HDL-pathname'
Syntax example:
vhdl object 'top.clk_en';

Parameters
HDL-pathname

The complete path to the VHDL object. If this name is not a constantthat
is, if it is a computed nameit is calculated after the final step of pre-run
generation. See 'HDL-pathname' on page 897 for a complete description
of HDL path syntax.

Description
Provides access for a VHDL signal referenced via tick access that includes a computed name. The name
of a signal accessed in this way cannot be deduced by Specman at the compilation time, and thus
requires a separate declaration.
vhdl object declarations for the same object can be repeated (to allow incremental building of e code),
but each repeated declaration must be identical.

Notes

Assignments to VHDL signals are not propagated until the start of simulation, so no pre-run
initialization of VHDL nets can be performed by Specman.

Specman e Language Reference


1999-2015

861
.

Product Version 15.1


All Rights Reserved.

vhdl object statements are considered extensions of sys. Accordingly, any non-constant expressions
cannot use variables that are not visible within sys. For vhdl object unit members, any non-constant
expressions are calculated within the context of a unit instance.
Whenever you add or modify a vhdl object unit member or statement or add an instance of a unit
containing a vhdl object unit member, you must create a new stubs file and then load the file into
the simulator. See When to Regenerate the Stubs Files in Specman Command Reference for more
information.

Example 1
In the following example, the vhdl object unit member ensures automatic access to the VHDL clk signal
during simulation. This access is required because the tick notation for accessing clk depends on a
computed name ((my_clk)). Specman evaluates the computed name after compilation, which is too
late to provide access to this signal during simulation.
Note If you deleted the vhdl object declaration from this example, you would have to provide access
via an access file or the +access option during an IES-XL simulation. Using the +access option can
significantly degrade simulation performance.
'unit verify {
...
my_clk: string;
keep my_clk == "~/tb/clk";
vhdl object '~/tb/clk';
event clk_rise is change('(my_clk)') @sim;
...
};
'

See Also

'HDL-pathname' on page 897

Specman File Conventions, Search Paths, and Log Files in Compiling, Linking, and Running

Specman
For third-party simulators:

write stubs in the Specman Command Reference

Specman e Language Reference


1999-2015

862

Product Version 15.1


All Rights Reserved.

17.3.2

vhdl code

Purpose
Write VHDL code directly to the stubs file

Category
Statement or unit member

Syntax
vhdl code {list-of-strings}
Syntax Example
vhdl code {
"library common_lib;";
"use common_lib.common_types.all;";
};
unit router {
vhdl code {
"library my_lib;";
"use my_lib.my_types.all;";
};
};

Parameters
list-of-strings Any list of strings that after concatenation creates any sequence of legal VHDL
code. Specman does not check for VHDL syntax errors. VHDL syntax errors are
identified only when you compile the file with the VHDL compiler.
The curly braces are required only if the list of strings contains more than one string.

Description
Specifies a list of VHDL strings to be included in the stubs file (specman_sim.vhd) before the
SPECMAN_REFERENCE entity. The stubs file contains code that enables some simulation-related
features. It is recommended to use vhdl code statements or unit members to modify this file rather than
to modify it by hand.

Specman e Language Reference


1999-2015

863
.

Product Version 15.1


All Rights Reserved.

Note

When vhdl code is used as a unit member, any non-constant expressions in the list of strings are
calculated within the context of a unit instance. Each unit instance adds a separate fragment of VHDL
code to the stubs file. When used as a statement, any non-constant expressions in the list of strings
are calculated within the context of sys.
Whenever you add or modify a vhdl code statement or unit member or add an instance of a unit
containing a vhdl code unit member, you must create a new stubs file. See When to Regenerate the
Stubs Files in Specman Command Reference for more information.

Example 1
A common use for the vhdl code statement is to include packages. For example, parameter types may be
declared in a different package from the one where the subprogram is declared. The example below adds
the common_types package defined in the common_lib library to the stubs file.
vhdl code {
"library common_lib;";
"use common_lib.common_types.all;";
};

The VHDL stubs file generated with this statement looks like this:
library common_lib;
use common_lib.common_types.all;
entity SPECMAN_REFERENCE is
end SPECMAN_REFERENCE;

Example 2
You can also use non-constants in vhdl code expressions. The following example configures the DUT
clock differently for each channel instance.
<'
unit channel {
chan_number: string;
keep chan_number == hdl_path();
s: string;
keep s == append("library worklib; \n",
"configuration phased_clocks of TOP is \n",
"
use worklib.all; \n",
"
for behavioral \n",
"
for CLK: clock \n",
"
use entity clkgen(",chan_number,"_clock); \n",
Specman e Language Reference
1999-2015

864

Product Version 15.1


All Rights Reserved.

"
end for; \n",
"
end for; \n",
"end phased_clocks;" );
vhdl code {s};
};
'>

This vhdl code unit member inserts the following VHDL code into the VHDL stubs file:
library worklib;
configuration phased_clocks of TOP is
use worklib.all;
for behavioral
for CLK: clock
use entity clkgen(CHAN0_clock);
end for;
end for;
end phased_clocks;
library worklib;
configuration phased_clocks of TOP is
use worklib.all;
for behavioral
for CLK: clock
use entity clkgen(CHAN1_clock);
end for;
end for;
end phased_clocks;

See Also

VHDL Statements and Unit Members on page 860

write stubs in the Specman Command Reference

17.3.3
Note

vhdl driver

See also the use of e ports to drive VHDL signals as described in Integrating the e Testbench

with VHDL in Specman Integrators Guide.

Purpose
Drive a VHDL signal continuously via the resolution function

Specman e Language Reference


1999-2015

865
.

Product Version 15.1


All Rights Reserved.

Category
Unit member

Syntax
vhdl driver 'HDL-pathname' using option, ...
Syntax examples:
unit top {
vhdl driver '~/top/data' using initial_value=32'bz,
disconnect_value=32'bz;
vhdl driver '(addr_name)' using initial_value= 1'bz,
delay= addr_delay;
};

Parameters
HDL-pathname

A full or a relative VHDL path to the signal. If the signal has more than
one driver, one driver in the DUT and one in Specman, for example, then
the signal must be of a resolved type (such as std_logic). If this name is
not a constant, it is calculated after the final step of pre-run generation.
See 'HDL-pathname' on page 897 for a complete description of HDL
path syntax.

option

A list of one or more of the following options separated by commas.


None of the options is required.

Specman e Language Reference


1999-2015

866

Product Version 15.1


All Rights Reserved.

disconnect_value=
[integer-expression |
verilog-literal]

Any legal integer expression specifying the value to be used on Specman


restore to disconnect the driver. The default is z. If this expression is not
a constant, it is calculated after the final step of pre-run generation.
Use a Verilog literal to specify values containing x or z. A Verilog literal
is a sized literal that can contain 0, 1, x, and z, for example 16'bx.
This value is used only by ModelSim VHDL when you restore Specman
after issuing a test command but do not restart the simulator. This value
should be set to a value that does not affect the overall value of the
resolved signal. For std_logic signals, the value should be z.
Notes

With IES-XL the disconnect_value is redundant. A simulator reset


removes previously created drivers, so they do not affect further
simulation.
If the VHDL signal name is a computed name then it will be computed
again before the restore. Thus, in order to correctly assign a
disconnect_value, it is important to keep the expressions used in the
computed name unchanged during the simulation session.

delay=
integer-expression

Any legal integer expression specifying a delay for all assignments. The
delay time units are determined by the current time unit setting. See vhdl
time on page 885 for information on how to set time units for Specman.
If this expression is not a constant, it is calculated after the final step of
pre-run generation.

mode=[INERTIAL |
TRANSPORT]

Used only when delay is also specified, this option specifies whether
pulses whose period is shorter than the delay are propagated through the
driver. INERTIAL specifies that such pulses are not propagated.
TRANSPORT, the default, specifies that all pulses, regardless of length,
are propagated.
The mode option also influences what happens if another driver (either
VHDL or another unit) schedules a signal change and before that change
occurs, this driver schedules a different change. With INERTIAL, the
first change never occurs.

Specman e Language Reference


1999-2015

867
.

Product Version 15.1


All Rights Reserved.

initial_value=
[integer-expression |
verilog-literal]

Any legal integer expression specifying an initial value for the signal. If
this expression is not a constant, it is calculated after the final step of
pre-run generation.
Use a Verilog literal to specify values containing x or z. A Verilog literal
is a sized literal that can contain 0, 1, x, and z, for example 16'bx.
When Specman is driving a resolved signal that is also driven from
VHDL, unless an initial value is specified, the signal value is X until the
first value is driven from Specman, even if a 0 or a 1 is driven from
VHDL.
Note IES-XL and ModelSim handle the initial value differently.
IES-XL assigns the initial value to the driver before the actual beginning
of simulation, but the propagation and resolution of drivers happens
when the simulator starts running, before the very first delta cycle.
ModelSim schedules the initial value as a transaction at the end of the
very first simulation delta cycle.

Description
The vhdl driver unit member identifies a VHDL signal that, when assigned to by an e method of that
unit, is driven continuously using the resolution function. In contrast, signal assignments made without
vhdl driver are over-ridden by any subsequent assignment from a VHDL process or from another e
method, rather than the two driven values being resolved.
To require resolution between VHDL process assignments and an e method assignment or between e
method assignments, you can use the vhdl driver unit member. The vhdl driver unit member creates a
driver that influences any assignments to the specified VHDL signal made by a method in the enclosing
unit or by a method in a struct enclosed by this unit.
You can create multiple drivers for the same signal by making multiple instances of a unit that contains
a vhdl driver unit member. In this case, the driver is created for every unit instance. This may be useful
when modeling multiple modules on a tri-state bus, for example. Multiple drivers can be created only for
signals of a resolved type.
There is a significant semantic difference between a verilog variable using drive statement/unit
member and a vhdl driver unit member. verilog variable using drive creates a single Verilog always
block for each actual Verilog signal. This means that there is one and only one driver for this signal.

Specman e Language Reference


1999-2015

868

Product Version 15.1


All Rights Reserved.

Notes

vhdl driver influences only assignments made by methods of the unit in which it was declared or
by methods of the structs nested in this unit. Therefore, you must use the vhdl driver unit member
in each unit that drives a particular signal; adding a vhdl driver unit member in only one of the units
that drives it is not sufficient.
vhdl driver is a unit member, not a statement. If you need to declare a vhdl driver and your
verification environment does not have any user-defined units, then you must explicitly extend sys
(sys is a unit):
<'
extend sys {
vhdl driver '/top/comp_io' using initial_value=1'bz;
};
'>

Any non-constant expressions are calculated within the context of the unit instance.
Currently, the continuous driving of VHDL signals is supported only inside a Specman tick that is
synchronized with a VHDL event. This means that you cannot apply the VHDL driver in a mixed
Verilog/VHDL design in a Specman tick triggered by a Verilog clock.
The vhdl driver unit member does not affect the VHDL stubs file, so it is not necessary to rewrite
the stubs file if you add or modify a vhdl driver unit member in your e code.
The pathname for multi-bit signals must be specified without a bit range, for example, sig. If you
include the bit range, for example, sig[1:0], Specman does not apply the driver.
IES-XL does not support drivers for multidimensional arrays.

Example
In the following example, the VHDL signal t is driven from the VHDL side and from two e unit
instances, drive0 and drive1. The simulation results are shown for IES-XL.

top.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity top is
end top;
architecture arch of top is
signal
signal
signal
signal

a
b
c
s

:
:
:
:

std_logic
std_logic
std_logic
std_logic

:=
:=
:=
:=

'0';
'0';
'0';
'1';

Specman e Language Reference


1999-2015

869
.

Product Version 15.1


All Rights Reserved.

signal t : std_logic ;
signal clk : std_logic := '0';
// comspec component not required when using irun
component comspec
end component;
for all: comspec use entity work.SPECMAN_REFERENCE (arch);
begin
clk_pr:process(clk) begin
clk <= not clk after 50 ns;
end process clk_pr;
shifter: process(clk) begin
if (clk'event AND clk = '1') THEN
a <= not a ;
b <= a xor b ;
c <= (a and b) xor c ;
if (b = '0' and c = '1') THEN
t <= '1' ;
elsif (b = '1' and c = '1') THEN
t <= '0' ;
else t <= 'Z' ;
end if ;
end if ;
end process shifter ;
I: comspec;
end arch ;

driver.e
<'
extend sys {
event clk is fall('~/top/clk')@sim ;
drive0 : drive is instance ;
drive1 : drive is instance ;
keep drive0.hdl_path() == "~/top";
keep drive0.name == "t";
keep drive1.hdl_path() == "~/top";
keep drive1.name == "t";
};
unit drive {
Specman e Language Reference
1999-2015

870

Product Version 15.1


All Rights Reserved.

name: string;
vhdl driver '(name)' using disconnect_value=1'bz,
initial_value = 1'bz;
driver() @sys.clk is {
'(name)' = 1 ;
wait cycle ;
'(name)' = 1'bz ;
wait [7] ;
'(name)' = 0 ;
wait cycle ;
stop_run() ;
};
run() is also { start driver() } ;
};
'>

Result (with IES-XL)


ncsim> probe -screen :t
Created probe 1
ncsim> run
Time: 50 NS: :t = 'Z'
Time: 100 NS: :t = '1'
Time: 200 NS: :t = 'Z'
Time: 450 NS: :t = '1'
Time: 650 NS: :t = '0'
Time: 850 NS: :t = 'Z'
Time: 900 NS: :t = '0'
ncsim> exit

See Also

'HDL-pathname' on page 897

VHDL Statements and Unit Members on page 860

Specman e Language Reference


1999-2015

871
.

Product Version 15.1


All Rights Reserved.

17.3.4

vhdl function

Purpose
Declare a VHDL function defined in a VHDL package

Category
Statement or unit member

Syntax
vhdl function 'identifier' using option, ...
Syntax examples:
unit calc {
vhdl function 'max' using
interface="(op1:word64; op2:word64) return word64",
library="work", package="arith_pkg";
vhdl function '(vhdl_min_name)' using
interface=intf,library=lib_name,package=package_name;
};

Parameters
identifier

Specman e Language Reference


1999-2015

The operator symbol (for example '"and') or the name of the


VHDL function as specified in the package. If the identifier
is not a constant, it is calculated after the final step of pre-run
generation.

872

Product Version 15.1


All Rights Reserved.

option

A comma-separated list of two or more of the following


options. The interface, library and package options are
required.

interface=
A legal string expression that specifies the interface list for
(string-exp) return return-subtype the function. If this expression is not a constant, it is
calculated after the final step of pre-run generation.
The legal syntax for this string is
[parameter-class] identifier :subtype[;...]
The only output of the function is the returned value.
The optional parameter class is constant or signal as
specified in the VHDL declaration and is transparent for
Specman.
The identifier does not have to be the name of the parameter
as specified in the package but the parameter subtype must
match exactly the package specification.
The type of the returned value must match exactly the
package specification. The type must also be one of the types
supported by Specman. See VHDL Object Types in the
Specman Integrators Guide.
library=string-exp

A legal string expression specifying the name of the VHDL


library containing the package where the function is defined.
If this expression is not a constant, it is calculated after the
final step of pre-run generation.

package=
string-exp

A legal string expression specifying the package name. If


this expression is not a constant, it is calculated after the final
step of pre-run generation.

alias=string-exp

A legal string expression that specifies the name with which


the function will be called from e. If this expression is not a
constant, it is calculated after the final step of pre-run
generation.
There are various reasons to use aliases. For example, an alias
is required when there are overloaded functions with the same
names but different interfaces. It must also be used for VHDL
functions that overload operator symbols (for example,
function +...) because the call from e cannot contain double
quotes.

Specman e Language Reference


1999-2015

873
.

Product Version 15.1


All Rights Reserved.

declarative_item=string-exp

A legal string expression that specifies one or more use


clauses that are placed in the stubs file at the local scope of
the function call rather than at the global scope of the
SPECMAN_REFERENCE entity. If this expression is not a
constant, it is calculated after the final step of pre-run
generation.
This option may prevent unwanted overwriting of
declarations in the stubs file. See Example 1 on page 879 for
an example of declarative_item used with vhdl procedure.

Description
Declares a VHDL function in e so that it can be called from a time-consuming method (TCM).
When there is a call to a procedure with a constant or signal parameter, the value of the constant or signal
is passed.
If there are functions in a single package that have the same name but different numbers or types of
parameters, make a separate declaration in e for each one you plan to call and specify a unique alias for
each declaration.

Notes

The VHDL function specifiers pure and impure are not supported.
If an alias is not used, then a call to a VHDL function requires the full VHDL name in the following
format: library_name.package_name.function_name.
Calls to VHDL functions are value-returning expressions. They are time-consuming and can only be
made from TCMs.
Function calls must explicitly specify actual valueseither scalars or lists of scalarsfor all
parameters. Default values for parameters are not supported.
When vhdl function is used as a unit member, any non-constant expressions are calculated within
the context of a unit instance. When used as a statement, any non-constant expressions are calculated
within the context of sys.
Whenever you add or modify a vhdl function statement in an e module, you must create a new stubs
file. See When to Regenerate the Stubs Files in Specman Command Reference for more information.

Example 1
VHDL allows overloading of subprogram names. It is possible, for example, to define two functions
with the name increment where the number and type of arguments or the return type may differ:

Specman e Language Reference


1999-2015

874

Product Version 15.1


All Rights Reserved.

function increment (a: integer) return integer is ...


function increment (a: integer; n:integer) return integer is ...

In cases like this, you must create an alias for each version that you intend to call.
vhdl function 'increment' using
interface="(a: integer) return integer",
library="work", package="pkg", alias="integer_inc_1";
vhdl function 'increment' using
interface="(a: integer; n: integer) return integer",
library="work", package="pkg",
alias="integer_inc_n";
extend sys {
event clk is rise ('top.clk') @sim;
test(a:int)@clk is {
assert 'integer_inc_1'(a) == 'integer_inc_n'(a,1);
};
};

Example 2
Another case where aliasing may be required is when a subprogram contains unconstrained array
parameters or unconstrained return values. For example, ToStdLogicVector accepts an integer and
converts it to a STD_LOGIC_VECTOR of the given length, probably truncating the value.
In order to support subprograms with unconstrained array parameters or return values, Specman must be
notified about all (or maximal) potential lengths in the given test. This is required because Specman
must provide a VHDL stub code that will specify the exact returned value type. Accordingly you may
need to use multiple aliases for the same VHDL function.
library ieee;
use IEEE.std_logic_1164.all;
package pkg is
function ToStdLogicVector(oper:INTEGER; length:NATURAL) \
return STD_LOGIC_VECTOR;
end pkg;

You must create an alias for each of the possible lengths of the returned value.
vhdl function 'ToStdLogicVector' using
interface= "(oper:INTEGER; length:NATURAL) \
return STD_LOGIC_VECTOR(0 to 31)",
library="lib", package="pkg",
Specman e Language Reference
1999-2015

875
.

Product Version 15.1


All Rights Reserved.

alias="ToStdLogicVector32";
vhdl function 'ToStdLogicVector' using
interface="(oper:INTEGER; length:NATURAL) \
return STD_LOGIC_VECTOR(15 downto 0)",
library="lib", package="pkg",
alias="ToStdLogicVector16";

See Also

'HDL-pathname' on page 897

VHDL Statements and Unit Members on page 860

show functions in the Specman Command Reference

show subprograms in the Specman Command Reference

write stubs in the Specman Command Reference

17.3.5

vhdl procedure

Purpose
Declare a VHDL procedure defined in a VHDL package

Category
Statement or unit member

Syntax
vhdl procedure 'identifier' using option, ...
Syntax Example
unit calc {
vhdl procedure 'do_arith_op' using
interface="(op1:integer; op2: integer; \
op_code: func_code; result: out integer)",
library="work", package="arith_pkg";
vhdl procedure '(vhdl_min_name)' using
interface=intf,library=lib_name,package=package_name;
};

Specman e Language Reference


1999-2015

876

Product Version 15.1


All Rights Reserved.

Parameters
identifier

The name of the VHDL procedure as specified in the package. If this


identifier is not a constant, it is calculated after the final step of pre-run
generation.

option

A comma-separated list of two or more of the following options. The


library and package options are required.

interface=
(string-exp)

A legal string expression that specifies the interface list for the
procedure. If this expression is not a constant, it is calculated after the
final step of pre-run generation.
The legal syntax for this string is
[ parameter_class ] identifier : [mode] subtype[;...]
The optional parameter class is constant, variable, or signal as
defined in the VHDL declaration and is transparent for Specman.
Mode is in, inout or out. The default mode is in.
The identifier does not have to be the name of the parameter as specified
in the package but the subtype must match exactly the specification in the
package. The subtype must also be one of the types supported by
Specman. See VHDL Object Types in the Specman Integrators Guide.
Note If the parameter class is signal, then the interface parameter
itself must not be defined as an e port. Use tick access instead to define
the interface parameter in e.

library=
string-exp

A legal string expression specifying the name of the library containing


the package where the procedure is defined. If this expression is not a
constant, it is calculated after the final step of pre-run generation.

package=
string-exp

A legal string expression specifying the package name. If this expression


is not a constant, it is calculated after the final step of pre-run generation.

alias=
string-exp

A legal string expression that specifies the name with which the
procedure will be called from e. If this expression is not a constant, it is
calculated after the final step of pre-run generation.
There are various reasons to use aliases. For example, an alias is required
when there are overloaded procedures with the same names but different
interfaces. It is also useful when two different procedures have the same
name but belong to different packages.

Specman e Language Reference


1999-2015

877
.

Product Version 15.1


All Rights Reserved.

declarative_item=
string-exp

A legal string expression that specifies a use clause that is placed at the
local scope of the procedure call rather than at the global scope of the
SPECMAN_REFERENCE entity in the stubs file. If this expression is
not a constant, it is calculated after the final step of pre-run generation.
This option prevents unwanted overwriting of declarations in the stubs
file. See Example 1 on page 879.

Description
Declares a VHDL procedure in e so that it can be called from a time-consuming method (TCM).
When there is a call to a procedure with a constant or variable parameter, the value of the constant or
variable is passed. Signal parameters are handled differently.
When there is a call to a procedure with a signal parameter of mode in, instead of passing the value of
the signal, it passes the signal object itself. Any reference to the formal parameter within the procedure
is exactly like a reference to the actual signal itself. A consequence of this is that if the procedure
executes a wait statement, the signal value may be different after the wait statement is completed and the
procedure resumes.
When there is a call to a procedure with a signal parameter of mode out, the procedure receives a
reference for the signal. When the procedure performs a signal assignment statement on the formal
parameter, the value is propagated to the actual signal parameter. Note that output parameters are
assigned in the default Specman way; the value is assigned immediately but is not forced and not
assigned via a VHDL driver.
If there are procedures in a single package that have the same name but different numbers or types of
parameters, you must make a separate declaration in e for each one you plan to call and specify a unique
alias for each declaration.
In order to allow multiple Specman threads to call the same time-consuming VHDL procedure
simultaneously and in parallel, you must create multiple unit members - one per such a thread. This may
be done, for example, by placing a vhdl procedure declaration in a unit, which logically maps the block
of the DUT to a Specman thread, and creating multiple instances of that unit. Specman creates a separate
VHDL process in the stubs file for each unit member, and you can then invoke the procedure
simultaneously from different unit instances.
There is a significant semantic difference between VHDL procedure/function and Verilog task/function
unit members. Verilog tasks are always located within Verilog modules. Thus, there may be multiple
instances of those tasks within a DUT. Accordingly, an HDL path of a corresponding unit in e maps
between the unit and a Verilog task instances. On the VHDL side, Specman supports only subprograms
that are declared in VHDL packages. Such subprograms have nothing to do with HDL paths.
Accordingly, the correspondence between e unit instance and a VHDL procedure unit member is

Specman e Language Reference


1999-2015

878

Product Version 15.1


All Rights Reserved.

completely abstractit just creates a separate process in the VHDL stub file. Such correspondence is
natural, because in VHDL the time-consuming package subprograms are re-entrant and may be called
simultaneously from parallel VHDL component instances.
The fact that VHDL subprogram unit members are not bound to HDL paths causes a difference in how
these subprograms may be called from nested unit instances. The essence of this difference is that if
some VHDL procedure/function is declared in a parent unit instance, then it may be called from other
units, instantiated below, without a duplication of the subprogram declaration.

Notes

Calls to VHDL procedures are time-consuming and can only be made from TCMs.
Passing a bit select of a signal parameter (for example, 'signal_name[3:7]') is not supported. (Passing
a bit select of a constant or variable is supported.)
Passing a signal parameter with @x, @z, or @n (for example, 'signal_name@x') is not supported.
(Passing a constant or variable with @x, @n, or @z is supported.)
If an alias is not used, then a call to VHDL procedure requires the full VHDL name in the following
format: library_name.package_name.function_name
You must explicitly pack all structs before passing them in as inputs to a procedure.
Procedure calls must explicitly specify actual values for all parameters. Default values for parameters
are not supported.
When vhdl procedure is used as a unit member, any non-constant expressions are calculated within
the context of a unit instance.When used as a statement, any non-constant expressions are calculated
within the context of sys.
Whenever you add or modify a vhdl procedure statement in an e module, you must create a new
stubs file. See When to Regenerate the Stubs Files in Specman Command Reference for more
information.

Example 1
This example shows how to handle the case where two different types from two different packages have
the same name (state). Using the declarative_item option to specify a use clause at the scope local to
the procedure avoids name collision.
vhdl procedure 'check_state' using
interface="(s:state)",
library="lib1",
package="procedures_pkg",
declarative_item="use lib1.fsm_types.all;";
vhdl procedure 'show' using
interface="(s:state)",
library="lib2",
Specman e Language Reference
1999-2015

879
.

Product Version 15.1


All Rights Reserved.

package="display_pkg",
declarative_item="use lib2.widget_types.all;";

Result
The specman_qvh.vhd file has the following structure. Note that the library declarations appear at the
global scope of the SPECMAN_REFERENCE entity. Any use clauses included with vhdl code
declarations would also appear at this scope. In contrast, the use clauses declared with declarative_item
appear at the scope of the appropriate function call.
entity SPECMAN_FMI is
end SPECMAN_FMI;
architecture fmi_stub of SPECMAN_FMI is
...
library IEEE;
use IEEE.std_logic_1164.all;
entity

specman_wave is

This example shows how to allow parallel invocation of the same procedure. There are two instances of
the unit transactor, which contains a vhdl procedure unit member. The TCM test() of each unit
instance is called during the run phase, simultaneously invoking two different VHDL processes. Notice
that the parentheses are required when calling the procedure from e, even though send_packet() has no
interface.
unit transactor {
vhdl procedure 'send_packet' using library="work",
package="pkg";
test() @sys.clk is {
'work.pkg.send_packet'();
};
};
extend sys {
event clk is rise ('top.clk') @sim;
transactor1: transactor is instance;
transactor2: transactor is instance;
run() is also {
start transactor1.test();
start transactor2.test();
};
};

Specman e Language Reference


1999-2015

880

Product Version 15.1


All Rights Reserved.

Example 2
This example illustrates the transmitting and receiving of a one-byte packet. The unit driver uses the
VHDL procedure transmit_packet_data to drive one bit of data per cycle. This procedure accepts two
input parameters by value and two signal parameters: an input, clock, and an output, the data bit.
The unit receiver uses the VHDL procedure receive_packet for reading the data. This procedure
accepts two input signal parameters: the clock and one bit of data (both are changing during the running
of the procedure) and one output parameter: the resulting package. The procedure waits for the rise of
the clock and then reads the new data.

The VHDL package:


package transmit_receive_pkg is
subtype data_range is integer range 1 to 8;
type packet_array is array (data_range) of bit;
procedure receive_packet (signal rx_data: in bit;
signal rx_clock: in bit;
data_buffer: out packet_array);
procedure transmit_packet_data (packet_type: in bit;
data_buffer: in bit_vector(6 downto 0);
signal rx_clock: in bit;
signal rx_data: out bit);
end transmit_receive_pkg;
package body transmit_receive_pkg is
procedure receive_packet (signal rx_data: in bit;
signal rx_clock: in bit;
data_buffer: out packet_array) is
begin
for index in data_range loop
wait until rx_clock = '1';
data_buffer(index) := rx_data;
end loop;
end receive_packet;
procedure transmit_packet_data ( packet_type: in bit;
data_buffer: in bit_vector(6 downto 0);
signal rx_clock: in bit;
signal rx_data: out bit ) is
begin
for index in 0 to 6 loop
Specman e Language Reference
1999-2015

881
.

Product Version 15.1


All Rights Reserved.

wait until rx_clock = '0';


rx_data <= data_buffer(index);
end loop;
wait until rx_clock = '0';
rx_data <= packet_type;
end transmit_packet_data;
end;

The entity and architecture:


use work.transmit_receive_pkg.all;
entity receiver is
end receiver;
architecture behavioral of receiver is
// SN component not required when using irun
component SN
end component;
for all: SN use entity work.specman_reference (arch);
signal data : bit;
signal clock: bit;
begin
clock_generator : process
begin
clock <= '0' after 2 ns, '1' after 10 ns;
wait for 10 ns;
end process clock_generator;
SN_INST: SN;
end behavioral;

The receiver unit


<'
vhdl object 'receiver.data';
vhdl object 'receiver.clock';
unit receiver {
vhdl procedure 'receive_packet' using interface= "( \
Specman e Language Reference
1999-2015

882

Product Version 15.1


All Rights Reserved.

signal rx_data: bit; signal rx_clock: bit; \


data_buffer: out packet_array)", library= "worklib",
package = "transmit_receive_pkg";
!received_packet : byte;
event clk is fall ('clock')@sim;
receive_packet() @clk is {
'worklib.transmit_receive_pkg.receive_packet'('data',
'clock',received_packet);
wait cycle;
outf("The packet that was received : \
%#x\n",received_packet);
wait cycle;
};
};
unit driver{
vhdl procedure 'transmit_packet_data' using interface= "( \
packet_type:in bit; \
data_buffer : in bit_vector(6 downto 0); \
signal rx_clock : in bit; signal rx_data : out bit )",
library= "worklib", package = "transmit_receive_pkg";
transmit_data : list of bit;
keep transmit_data.size() == 7;
packet_type

: bit;

event clk is rise ('clock')@sim;


send_packet()@clk is{
'worklib.transmit_receive_pkg.transmit_packet_data'(
packet_type,transmit_data,'clock','data');
};
};
extend sys{
keep agent() == "ncvhdl";
driver
:driver
is instance;
receiver :receiver is instance;
keep driver.hdl_path() == "/";
keep receiver.hdl_path() == "/";

Specman e Language Reference


1999-2015

883
.

Product Version 15.1


All Rights Reserved.

run() is also {
start driver.send_packet();
start receiver.receive_packet();
start do_check();
};
do_check()@receiver.clk is {
var transmit_packet: byte;
unpack(NULL,driver.transmit_data.reverse(),
transmit_packet[7:1]);
transmit_packet[0:0] = driver.packet_type;
outf("The packet that was transmitted : \
%#x\n",transmit_packet);
wait [10]*cycle;
check that (transmit_packet == receiver.received_packet)
else dut_error(" the data did not pass correctly");
stop_run();
};
};
'>

Results (with IES-XL)


ncsim> run
The packet that was transmitted :
0x93
The packet that was received :
0x93
Last specman tick - stop_run() was called
...

See Also

'HDL-pathname' on page 897

VHDL Statements and Unit Members on page 860

show procedures in the Specman Command Reference

show subprograms in the Specman Command Reference

write stubs in the Specman Command Reference

Specman e Language Reference


1999-2015

884

Product Version 15.1


All Rights Reserved.

17.3.6

vhdl time

Purpose
Sets VHDL time resolution

Category
Statement

Syntax
vhdl time integer-exp time-unit
Syntax Example
vhdl time 100 ns;

Parameters
integer-exp

A legal integer expression. If the expression is not a constant, it is calculated after


the final step of pre-run generation.

time-unit

Any valid VHDL time unit.

Description
Sets the time resolution to the specified timescale. This timescale is used to scale:

Delays in Specman temporal expressions

Delays specified in vhdl driver unit members

Simulation time as shown in sys.time, a 64-bit integer field that stores Specman time.

If you use ModelSim, the default resolution always matches the settings chosen on the simulator side in
the initialization file or with the simulator invocation option. You can change the default to take into
account vhdl time statements in your code by setting the -enable_vhdl_time_mti simulation config
option, as described in configure simulation in the Specman Command Reference.

Notes

The vhdl time statement does not affect the stubs file, so it is not necessary to rewrite the stubs file
if you change the timescale.

Specman e Language Reference


1999-2015

885
.

Product Version 15.1


All Rights Reserved.

vhdl time cannot be used as a unit member.


If you use a non-constant expression in a vhdl time statement, this expression is computed in the
context of sys and so must be visible in that context.

Example 1
The following statement sets the time resolution to 100ns.
vhdl time 100 ns;

Example 2
In this example, the time resolution is not calculated until after the final step of pre-run generation.
vhdl time num ns;
extend sys {
num:int;
keep num == 100;
};

See Also

VHDL Statements and Unit Members on page 860

vhdl driver on page 865

17.4 Simulation-Related Actions


There are two simulation-related actions in e:

force on page 886

release on page 892

17.4.1

force

Purpose
Force a value on an HDL object using tick access notation

Specman e Language Reference


1999-2015

886

Product Version 15.1


All Rights Reserved.

Note See also force port$ on page 348 and force port$[ : ] on page 350 for the corresponding action
for use with ports.

Category
Action

Syntax
force 'HDL-pathname' = exp
Syntax Example
force '~/top/sig' = 7;

Parameters
HDL-pathname

The full path name of an HDL object, optionally including expressions. See
'HDL-pathname' on page 897 for more information.

exp

Any scalar expression or literal constant, as long as it is composed only of 1's and
0's. No x or z values are allowed. Thus 16'hf0f1 or (sys.my_val + 5) are legal.

Description
Forces an HDL object to a specified value, overriding the current value and preventing the DUT from
driving any value. If you force a part of a vectored object, the force action is propagated to the rest of the
object.
Note You can also pass force and deposit simulator commands with the predefined routine
simulator_command().

With a Verilog Design


You can apply a force action to any net or wire that has been declared forcible with the verilog variable
statement.
The effect of a force action on a Verilog design is that all preceding and subsequent non-forced
assignments from Specman or from the DUT to the same object including those within the same
Specman tick are ignored until a subsequent force action from e or until freed by a release action
from e. The only exception is that if you force different parts of a vectored object in the same Specman
tick, the actions are accumulated and applied together at the end of the tick.
Forcing of Verilog registers is not supported.
Specman e Language Reference
1999-2015

887
.

Product Version 15.1


All Rights Reserved.

With a VHDL Design


You can force signals of a scalar integer or enumerated type as well as binary array type, such as arrays
of std_logic and bit vectors. No declaration is required for VHDL objects.
The effect of the force action on a VHDL design is:

A release action is required to allow the object to be driven by the DUT.

Each new action from e overrides the previous one without an explicit release action.

To change the behavior of proprietary VHDL adapters to be compatible with this behavior, you can call
the global set_assign_after_force_compatible() method as follows before simulation starts:
Specman > set_assign_after_force_compatible(TRUE)

Setting this method is not required for any of the simulators supported by Specman.

Notes

Forcing signals is always costly to performance.


When you force an HDL object, the value is applied immediately, without a delay, even if a drive
delay has been specified for the object.

Example 1
This example shows the effect of force and release actions with Incisive simulator and a Verilog design.

top.v
module top();
reg clk;
wire [7:0] data;
initial begin
clk = 0;
forever begin
#50 clk = ~clk;
end
end
// monitors
always @(data) $display ("%t : data = %b", $time, data);
endmodule

Specman e Language Reference


1999-2015

888

Product Version 15.1


All Rights Reserved.

test.e
struct sim {
event clk is rise ('~/top/clk')@sim;
m() @clk is {
'~/top/data' = 8'b10101010;
force '~/top/data[3:0]' =0;
'~/top/data[7:4]' = 4'b0000;
wait cycle;
'~/top/data' = 8'b10011001;
wait cycle;
release '~/top/data[7:0]';
wait cycle;
'~/top/data' = 8'b11111111;
wait [2]* cycle;
stop_run();
};
};
extend sys {
sim;
setup() is also {
set_config(print, radix, bin);
};
run() is also {
start sys.sim.m();
};
};

verilog.e
verilog variable '~/top/data[7:0]' using wire, forcible;

Result
ncsim> run
0 : data = zzzzzzzz
50 : data = 10100000
Specman e Language Reference
1999-2015

889
.

Product Version 15.1


All Rights Reserved.

250 : data = zzzzzzzz


350 : data = 11111111
Last specman tick - stop_run() was called
Normal stop - stop_run() is completed
Checking the test ...
ncsim>

Example 2
This example shows the effect of force and release actions with Incisive simulator and a VHDL design.

top.vhd
use std.textio.all;
library IEEE;
use IEEE.std_logic_1164.all;
entity top is
end top;
architecture arc of top is
signal clk : std_logic := '0';
signal data: std_logic_vector (7 downto 0);
// comspec component not required when using irun
component comspec
end component;
for all: comspec use entity work.SPECMAN_REFERENCE (arch);
begin
I: comspec;
clk <= not clk after 50 ns;
end arc;

test.e
struct sim {
event clk is rise ('~/top/clk')@sim;
m() @clk is {
'~/top/data' = 8'b10101010;
force '~/top/data[3:0]' =0;
'~/top/data[7:4]' = 4'b0000;

Specman e Language Reference


1999-2015

890

Product Version 15.1


All Rights Reserved.

wait cycle;
'~/top/data' = 8'b10011001;
wait cycle;
release '~/top/data[7:0]';
wait cycle;
'~/top/data' = 8'b11111111;
wait [2]* cycle;
stop_run();
};
};
extend sys {
sim;
setup() is also {
set_config(print, radix, bin);
};
run() is also {
start sys.sim.m();
};
};

vhdl.e
vhdl object '~/top/data';

Result
ncsim> probe -screen :data
ncsim> run
Time: 50 : data = "10100000"
Time: 250 : data = "10011001"
Time: 350 : data = "11111111"

See Also

'HDL-pathname' on page 897

force port$ on page 348

Specman e Language Reference


1999-2015

891
.

Product Version 15.1


All Rights Reserved.

force port$[ : ] on page 350

release on page 892

17.4.2

release

Purpose
Remove a force action from an HDL object

Category
Action

Syntax
release 'HDL-pathname'
release simple-port-exp
Syntax Example
release 'TOP.sig';

Parameters
HDL-pathname

The full path name of an HDL object previously specified in a force action.

Description
Releases the HDL object that you have previously forced.
With a Verilog Design
If the released object is a Verilog register and it has no other driver, the current value of the register is
retained. If the release object is a Verilog wire and it has no other driver, it floats to high-impedance (all
z).
With a VHDL Design
The effect of a release action depends on the simulators procedural interface.
For IES-XL, releasing a forced signal immediately unfreezes its drivers, and the resolved value is
assigned to the signal. For example:
Specman e Language Reference
1999-2015

892

Product Version 15.1


All Rights Reserved.

IES with driver


DUT: sig <= '1';
Specman: force sig = '0';
Specman: release sig
print sig -> '1'

For signals with no drivers, the last assigned value before the force action is re-assigned. If there was no
assignment, the initial value is assigned. If there was no initial value, the default value is assigned. For
example:
IES with no driver
signal sig : std_logic := 'Z'
Specman: sig = 'X'
Specman: force sig = '0'
Specman: release sig
print sig -> 'X'
IES with no driver
signal sig : std_logic := 'Z'
Specman: force sig = '0'
Specman: release sig
print sig -> 'Z'
IES with no driver
Specman: force sig = '0'
Specman: release sig
print sig -> 'U'

For ModelSim, the behavior is different from IES-XL if the signal does not have drivers. For example,
if a signal is forced and assigned only from e, the last forced value is retained. If there was no forced
value, the default value is assigned. For example:
ModelSim with no driver
Specman: force sig = '0';
Specman: release sig
print sig -> '0'

Example 1
This example shows the effect of force and release actions with IES-XL and a Verilog design.

top.v
module top();
reg clk;
wire [7:0] data;

Specman e Language Reference


1999-2015

893
.

Product Version 15.1


All Rights Reserved.

initial begin
clk = 0;
forever begin
#50 clk = ~clk;
end
end
// monitors
always @(data) $display ("%t : data = %b", $time, data);
endmodule

test.e
struct sim {
event clk is rise ('~/top/clk')@sim;
m() @clk is {
'~/top/data' = 8'b10101010;
force '~/top/data[3:0]' =0;
'~/top/data[7:4]' = 4'b0000;
wait cycle;
'~/top/data' = 8'b10011001;
wait cycle;
release '~/top/data[7:0]';
wait cycle;
'~/top/data' = 8'b11111111;
wait [2]* cycle;
stop_run();
};
};
extend sys {
sim;
setup() is also {
set_config(print, radix, bin);
};
run() is also {
start sys.sim.m();
};
Specman e Language Reference
1999-2015

894

Product Version 15.1


All Rights Reserved.

};

verilog.e
verilog variable '~/top/data[7:0]' using wire, forcible;

Result
ncsim> run
0 : data = zzzzzzzz
50 : data = 10100000
250 : data = zzzzzzzz
350 : data = 11111111
Last specman tick - stop_run() was called
Normal stop - stop_run() is completed
Checking the test ...
ncsim>

Example 2
This example shows the effect of force and release actions with IES-XL and a VHDL design.

top.vhd
use std.textio.all;
library IEEE;
use IEEE.std_logic_1164.all;
entity top is
end top;
architecture arc of top is
signal clk : std_logic := '0';
signal data: std_logic_vector (7 downto 0);
// comspec component not required when using irun
component comspec
end component;
for all: comspec use entity work.SPECMAN_REFERENCE (arch);
begin
I: comspec;
clk <= not clk after 50 ns;
Specman e Language Reference
1999-2015

895
.

Product Version 15.1


All Rights Reserved.

end arc;

test.e
struct sim {
event clk is rise ('~/top/clk')@sim;
m() @clk is {
'~/top/data' = 8'b10101010;
force '~/top/data[3:0]' =0;
'~/top/data[7:4]' = 4'b0000;
wait cycle;
'~/top/data' = 8'b10011001;
wait cycle;
release '~/top/data[7:0]';
wait cycle;
'~/top/data' = 8'b11111111;
wait [2]* cycle;
stop_run();
};
};
extend sys {
sim;
setup() is also {
set_config(print, radix, bin);
};
run() is also {
start sys.sim.m();
};
};

vhdl.e
vhdl object '~/top/data';

Specman e Language Reference


1999-2015

896

Product Version 15.1


All Rights Reserved.

Result
ncsim> probe -screen :data
ncsim> run
Time: 50 : data = "10100000"
Time: 250 : data = "10011001"
Time: 350 : data = "11111111"

See Also

'HDL-pathname' on page 897

force on page 886

17.5 Simulation-Related Expressions


This section contains:

'HDL-pathname' on page 897

specman deferred on page 899

17.5.1

'HDL-pathname'

Purpose
Accessing HDL objects, using full-path-names

Category
Expression

Syntax
'HDL-pathname[index-exp | bit-range] [@(x | z | n)]'
Syntax Example
'~/top/sig' = 7;
print '~/top/sig[7:0]';
print '~/top/sig[0]';

Specman e Language Reference


1999-2015

897
.

Product Version 15.1


All Rights Reserved.

Parameters
HDL-pathname

The full path name of an HDL object, optionally including expressions and
composite data. The name must comply with one of the conventions described
in HDL Object Names in the Specman Integrators Guide. The object type must
be one of the object types described in Supported HDL Object Types in the
Specman Integrators Guide.

bit-range

A bit range has the format [high-bit-num:low-bit-num] and is extracted from the
object from high bit to low bit. Slices of buses are treated exactly as they are in
HDL languages. They must be specified in the same direction as in the HDL
code and reference the same bit numbers.

index-exp

Accesses a single bit of a Verilog vector, a single element of a Verilog memory,


or a single vector of a VHDL array of vectors.

@x | z

Sets or gets the x or z component of the value. When this notation is not used in
accessing an HDL object, Specman translates the values of x to zero and z to
one.
When reading HDL objects using @x (or @z), Specman translates the specified
value (x or z) to one, and all other values to zero. When writing HDL objects, if
@x (or @z) is specified, Specman sets every bit that has a value of one to x (or
z). In this way, @x or @z acts much like a data mask, manipulating only those
bits that match the value of x or z.

@n

When this specifier is used for driving HDL objects, the new value is visible
immediately (now). The default mode is to buffer projected values and update
only at the end of the Specman tick. If reading a value using @n then the
projected simulator value (the value currently stored in the buffer) can be seen.
Note Specman does not access the simulator to get this value; it simply
retrieves the projected value currently stored in the buffer.

Description
Accesses Verilog and VHDL objects from e.

Note
In general, you can access HDL objects using the 'HDL-pathname' expression. In order to enable some
non-trivial capabilities, however, you must also use verilog or vhdl statements.

Specman e Language Reference


1999-2015

898

Product Version 15.1


All Rights Reserved.

See Also

Reading and Writing HDL Objects in the Specman Integrators Guide

17.5.2

specman deferred

Purpose
Identify a deferred Verilog `define

Category
Verilog expression

Verilog Syntax
`define macro-name default-value // specman deferred
Syntax Example
`define bus_width 64 // specman deferred

Parameters
macro-name

Any legal Verilog identifier.

default-value

A constant expression. This value is used as the definition of the `define


unless you over-write it with another value. The size and type of this value is
used to determine the expected type and size of the runtime expressions.
Thus, if this value is longer than 32 bits, its size must be explicitly specified.

// specman deferred The // specman deferred comment must appear on the same line of the file
that specifies the `define. This comment can contain any number of spaces or
tabs.

Description
Deferred Verilog `defines let you use Verilog definitions without specifying their final values at compile
time. Instead, you can redefine their values just prior to use.
This feature lets you compile and link a single executable for all tests and then load in different Verilog
`defines definitions for different tests.

Specman e Language Reference


1999-2015

899
.

Product Version 15.1


All Rights Reserved.

All non-deferred `defines are substituted in place during parsing. References to deferred `defines are
resolved at run time.

Notes

Deferred 'defines cannot be used in other Verilog `defines used by Specman.

You can only redefine the value of a `define; you cannot redefine its type or width. For example:
The following lines define a `define with the default width of 32 bits:
define MY_MASK 0

// specman deferred

If later on during the run MY_MASK is defined with a different type or length, for example,
define MY_WRONG_MASK 64'bz

a Specman error occurs.

Whether a `define is deferred or not is established at its very first occurrence and cannot be changed
by any subsequent occurrence of this macro.
The use of deferred macros causes some performance overhead, which is equivalent to accessing an
entry in a table when using a function call for this purpose.

See Also

Using Verilog Defines in the Specman Integrators Guide

show defines in the Specman Command Reference

verilog import on page 840

17.6 Simulation-Related Routines


The following routines perform functions related to simulation:

simulator_command() on page 900

$sn() on page 901

stop_run() on page 902

17.6.1

simulator_command()

Purpose
Issue a simulator command from e code

Specman e Language Reference


1999-2015

900

Product Version 15.1


All Rights Reserved.

Category
Predefined routine

Syntax
simulator_command(command: string)
Syntax Example
simulator_command("find carry out");

Parameters
command

A valid simulator command, enclosed in double quotes.

Description
Passes a command to the simulator from e. The command returns no value. The output of the command
is sent to standard output and to the log file.
Notes

When you are using VCS, simulator_command() is supported with the UCLI (Unified Command
Line Interface) debugging tool only. simulator_command() is not supported with the CLI tool.
Simulator commands that advance timelike run, next, step, continue, or finishcannot be executed
via simulator_command().
Simulator commands that result in an action in the context of Specmansuch as reset or restart, for
examplemay result in undefined behavior. Such commands should not be used with
simulator_command().

17.6.2

$sn()

Purpose
Issue a Specman command from HDL code

Category
Predefined routine

Specman e Language Reference


1999-2015

901
.

Product Version 15.1


All Rights Reserved.

Syntax
$sn(command: string)
Syntax Example
$sn("set_config(print,radix,bin);");

Parameters
command

A valid Specman command, enclosed in double quotes or a string variable containing a


Specman command.

Description
Passes a command to Specman from HDL code. The command returns no value. The output of the
command is sent to standard output and to the log file.
For example, the following code might appear in the file top.sv:
module top;
...
string sn_cmd = "set_config(print,radix,bin);";
initial begin
$sn(sn_cmd);
end
...
endmodule

Note You can use the tcl_simcmderror Tcl variable to check if an sn command succeeds. For
example, the following command, which tries to load an e file that does not exist, sets tcl_simcmderror
to 1:
ncsim> sn load invalid-e-file-name // sets tcl_simcmderror

For more information, see the description of tcl_simcmderror in Setting Variables in Debugging Your
Design.

17.6.3

stop_run()

Purpose
Stop a simulation run cleanly

Specman e Language Reference


1999-2015

902

Product Version 15.1


All Rights Reserved.

Category
Predefined routine

Syntax
stop_run()
Syntax Example
stop_run();

Description
Stops the simulator and initiates post-simulation phases. The following things occur when stop_run() is
invoked:
1.

The quit() method of each struct under sys is called. Each quit() method emits a quit event for that
struct instance at the end of the current tick.

2.

The scheduler continues running all threads until the end of the current tick.

3.

At the end of the current tick, the extract, check, and finalize test phases are performed.

4.

If a simulator is linked in to Specman, Specman terminates the simulation cleanly after the test is
finalized.

Notes

This method must be called by a user-defined method or TCM to stop the simulation run cleanly.
You should not extend or modify the stop_run() method. If you want something to happen right after
you stop the run, you can extend sys.extract().
Executing a tick after calling stop_run() is considered an error. This includes executing a tick to call
a Verilog function or task.
The actual threads are not removed until the end of the tick, so that you can see them using the
debugger.
If the simulator exit command is called before stop_run(), the global methods for extracting, checking
and finalizing the test are called.

Example
verilog import macros.v;
extend sys {
event pclk is rise ('`TOP.pclk');
Specman e Language Reference
1999-2015

903
.

Product Version 15.1


All Rights Reserved.

driver: dut_driver;
};
struct dut_driver {
ld: list of int(bits: `WORD_WIDTH);
keep ld.size() in [1..30];
stimuli() @sys.pclk is {
'`READY' = 1;
for each in ld {
wait until true('`READY' == 1);
'`TOP.data_in' = it;
wait [`TRANS_DELAY];
};
stop_run();
};
run() is also {
start stimuli();
};
};

See Also

The quit() Method of any_struct or any_unit on page 1189

configure run in the Specman Command Reference

Specman e Language Reference


1999-2015

904

Product Version 15.1


All Rights Reserved.

18

Sequence Elements

This chapter describes the elements that define and create sequences:

The sequence Statement on page 905

<sequence-name>_kind on page 908

any_sequence_item on page 909

any_sequence on page 911

any_sequence_driver on page 918

Sequence Item do Actions on page 933

Pseudo-Routines for Tree Constraints on page 937

See Also

Creating and Using Sequences in the Creating e Testbenches

Sequence Commands in Specman Command Reference

Sequences: Constructing Test Scenarios in the OVM e User Guide

18.1 The sequence Statement


18.1.1

sequence

Purpose
Define the sequence struct and the sequence driver unit

Specman e Language Reference


1999-2015

905
.

Product Version 15.1


All Rights Reserved.

Category
Statement

Syntax
sequence sequence_name [using sequence_option,...];

Options
item = item_type

The item to be used in the sequence. This item must be already defined
and inherits from any_sequence_item. The item struct is extended by
the sequence statement.
If the item option is not used, then this is assumed to be a virtual
sequence (see Using Virtual Sequences in the Creating e Testbenches).
Note You cannot use the same item type in two different sequence
statements in the same environment. See Example 3 on page 907 for
the workaround to this limitation.

created_kind = kind_name

The name of the associated kind enumerated type to be created


(default: sequence_name_kind).

created_driver = driver_name

The name of the associated sequence driver to be created (default:


sequence_name_driver).

sequence_type =
base_sequence_name

The name of the sequence struct your sequence inherits from (default:
any_sequence).
For more information, see Creating a Common Base for Your
Sequences and Sequence Drivers in the Creating e Testbenches.

sequence_driver_type =
base_sequence_driver_name

The name of the sequence driver unit your sequence driver inherits
from (default: any_sequence_driver).
For more information, see Creating a Common Base for Your
Sequences and Sequence Drivers in the Creating e Testbenches.

Description
The sequence statement creates the following:

A new enumerated type called sequence-name_kind.

A new sequence struct, which inherits from the predefined any_sequence.

Specman e Language Reference


1999-2015

906

Product Version 15.1


All Rights Reserved.

A new sequence driver unit, which inherits by default from any_sequence_driver.

The sequence statement does not create the item struct, but it extends it by adding a reference to the
sequence driver that facilitates the actual driving of the item to the DUT and a backpointer to the
sequence in which an item was created.
Note The only way to define sequences or sequence drivers is by the sequence statement; however,
you can define a base sequence (or a base sequence driver) by deriving it from any_sequence (or from
any_sequence_driver). For more information see Creating a Common Base for Your Sequences and
Sequence Drivers in the Creating e Testbenches.

Example 1

Defining a BFM sequence for ATM cells

sequence ex_atm_sequence using item=ex_atm_cell;

This statement assumes that an ex_atm_cell struct already exists. It defines:


Struct

ex_atm_sequence (inherits from any_sequence)

Type

ex_atm_sequence_kind

Unit

ex_atm_sequence_driver (inherits from any_sequence_driver)

Example 2

Defining a virtual sequence for an SoC environment

sequence soc_sequence;

This statement defines the soc_sequence struct, the soc_sequence_kind type, and the
soc_sequence_driver unit.

Example 3

Creating Subtypes of the Same Item Type

You cannot use the same item type in two different sequence statements in the same environment. You
can get around this limitation, however, by creating two (or more) subtypes and use the subtypes in the
sequences (a different subtype for each sequence type).
For example, you could create two different sequences for ATM cells as follows:
1.

Define the type to create the subtypes.


For example:
<'
type cell_seq_kind: [A, B];
'>

2.

Add the type to the item for which you want to create sequences.
For example:

Specman e Language Reference


1999-2015

907
.

Product Version 15.1


All Rights Reserved.

<'
extend ex_atm_cell {
seq_kind: cell_seq_kind;
};
'>

3.

Use the sequence statement to create two different sequences for the two different subtypes.
For example:
<'
sequence atm_A using item=A ex_atm_cell;
sequence atm_B using item=B ex_atm_cell;
'>

See Also

The sequence Statement on page 905

<sequence-name>_kind on page 908

any_sequence_item on page 909

any_sequence on page 911

any_sequence_driver on page 918

18.2 <sequence-name>_kind
The sequence statement creates a new enumerated type called sequence-name_kind. This type has
the following predefined values:
MAIN

Identities a sequence that loops n times creating the sequence field


(randomly unless constrained). The driver contains an instance of the MAIN
sequence, which is started automatically upon run().

RANDOM

Same as MAIN but used inside other sequences.

SIMPLE

Identifies a sequence that contains a single item.

Notes

The sequence kind type is declared as const in the sequenceit cannot be changed during runtime.
Cadence recommends that all enumerated values be stated in uppercase letters. In addition, all
user-defined sequence kinds should be defined as uppercase names. For example:
extend ex_atm_sequence_kind: [LEGAL_CELLS];
extend LEGAL_CELLS ex_atm_sequence {

Specman e Language Reference


1999-2015

908

Product Version 15.1


All Rights Reserved.

body() @driver.clock is only { ... };


};
extend MAIN ex_atm_sequence {
body() @driver.clock is only { ... };
};

18.3 any_sequence_item
Notes

The driver field is not defined in any_sequence_item. For this field to be defined, you must use the
item or sequence in a sequence statement.
The get_driver() method is declared as undefined in any_sequence_item. For this method to be
defined, you must use the item or sequence in a sequence statement.
Never use is only on the pre_generate() or post_generate() of items. The parent_sequence and
driver of fields are assigned in the pre_generate() of any_sequence_item.
Some of the methods in Table 18-2 (any_sequence interface) are inherited from the
any_sequence_item interface shown in Table 18-1.

Table 18-1

any_sequence_item Interface

Struct Member

Description

Read Only Member (can only be accessed)

get_depth(): int

Depth from the sequence driver, valid from


pre-generation.

get_driver(): driver_name

Returns the driver for an item.

!parent_sequence: any_sequence;

Added by the sequence statement, this is a


backpointer to the sequence in which an item was
created. Assigned automatically in the
pre_generate() of the item.

do_location(): string

Returns a string describing the source location of the


do action that generated the current item.
Not relevant for sequence_items not created via the do
action.

Specman e Language Reference


1999-2015

909
.

Product Version 15.1


All Rights Reserved.

Table 18-1

any_sequence_item Interface

Struct Member

Description

is_relevant(): bool

Apply a condition for performing a do item action, so


that the do action will not be scheduled until
is_relevant() returns TRUE. See
any_sequence_item.is_relevant() on page 910 for
more information.

item_discarded(item:any_sequence_item):

A hook method that gets called automatically every


time a generated item is removed from the driver
queue before actually being sent to the BFM (more
precisely before it is returned from a
get/try_next_item() call). This may happen whenever
a sequence is stopped or a driver is rerun while one or
more generated items are still pending (typically due to
item-level is_relevant() returning FALSE). The
discarded item is passed as parameter.

Read/Write Member (can also be set, constrained, or implemented)

driver: driver_name

18.3.1

Added by the sequence statement, this is a reference


to the sequence driver that facilitates the actual
driving of the item to the DUT. It is soft-constrained to
be its parent sequences driver.

any_sequence_item.is_relevant()

Purpose
The is_relevant() method controls the timing of the drivers execution of the do request.

Syntax
[sequence-exp.]is_relevant(): bool

Parameters
None

Specman e Language Reference


1999-2015

910

Product Version 15.1


All Rights Reserved.

Description
is_relevant() is a non-time-consuming method.
For sequences, is_relevant() returns TRUE if the sequence is currently allowed to do items. If
is_relevant() returns FALSE, the driver will skip this request in the current cycle.
For sequence items, is_relevant() returns TRUE if the item can be passed to the BFM at this current
time. If is_relevant() returns FALSE, the driver will skip this item, and pass the next relevant item (if
any) to the BFM. The next time an item is needed, the original items relevancy is again checked by
is_relevant().
By default, is_relevant() returns TRUE. You can implement it to respond to the changing conditions of
the simulation. It is particularly useful for sequences and sequence items used by reactive agents.

18.4 any_sequence
Notes

any_sequence inherits from any_sequence_item.


The driver field and kind field are not defined in any_sequence. For these fields to be defined, you
must use the item or sequence in a sequence statement.
The get_driver() method is declared as undefined in any_sequence. For this method to be defined,
you must use the item or sequence in a sequence statement.
Never use is only on the pre_generate() or post_generate() of sequences. The parent_sequence and
driver of fields are assigned in the pre_generate() of any_sequence_item.
Some of the methods in Table 18-2 (any_sequence interface) are inherited from the
any_sequence_item interface shown in Table 18-1.

Table 18-2

any_sequence Interface

Struct Member

Description

Read Only Member (can only be accessed)

kind: kind_name;

kind is not a field of any_sequence. It is a field of the specific sequence


struct expanded by the sequence statement. Its type is the corresponding
enum type.
This field is used for creating sequence subtypes with various behavior. It
is declared constonce the value is generated, you must not change its
value procedurally.

get_depth(): int

Depth from the sequence driver, valid from pre-generation.

Specman e Language Reference


1999-2015

911
.

Product Version 15.1


All Rights Reserved.

Table 18-2

any_sequence Interface

Struct Member

Description

get_driver():
driver_name

Return the driver for a sequence.

!parent_sequence:
any_sequence;

Backpointer to the sequence in which this sequence was created. Assigned


automatically in pre_generate() of the sequence if such a parent exists.

get_index(): int

Starts at 0 and gets incremented after every do.


Provides a declarative style.

get_priority(): int

Returns an integer indicating the priority of the sequence.

grab(driver:
any_sequence_driver)
@sys.any is undefined

Grab the sequence driver for exclusive access and returns when you have
exclusive access. See any_sequence.grab() on page 914 for more
information.

is_blocked(): bool

Indicate whether the sequence is blocked. See


any_sequence.is_blocked() on page 915 for more information.

start_sequence()

Starts sequence activity by starting body(). See any_sequence.grab() on


page 914 for more information.
Note

stop()
ungrab(driver:
any_sequence_driver)
is undefined

Call this method instead of starting body() directly.

Terminates my body(), if it exists. See any_sequence.stop() on page 917


for more information.
Releases the grab on a sequence driver and returns immediately. See
any_sequence.ungrab() on page 917 for more information.

Read/Write Member (can also be set, constrained, or implemented)

driver: driver_name

Driver for the sequence, soft-constrained to be its parent sequences


driver.
The driver field is not defined in any_sequence. For this fields to be
defined, you must use the item or sequence in a sequence statement.

Specman e Language Reference


1999-2015

912

Product Version 15.1


All Rights Reserved.

Table 18-2

any_sequence Interface

Struct Member

Description

initial_priority: int

A const generatable field that defines the priority of the sequence. When
the sequence is generated, by default the priority set to be the same as its
parent sequences priority. If the generated sequence does not have a
parent (when it is invoked with start_sequence() rather than with do), it
defaults to 100.
Because it is defined as const, this fields value is determined once and for
all at generation. Generation can be controlled either by constraints, by
direct assignment in the scope of pre_generate() or post_generate(), or
by calling any_sequence.set_priority().
Note

Actual priority values are considered during the sequencer arbitration


cycle. Thus, changing a sequence priority may affect its pending do
requests at any time before its item is delivered.
When sequences are displayed (by printing or in the data-browser), the
actual priority of the sequence is presented.

set_priority(new_val:
int)

Can be called in the scope of pre_generate() or post_generate() to set the


priority of the sequence relative to other sequences.

@ended

Emitted immediately after body() is finished.

@started

Emitted just before body() is called.

body() @driver.clock is
empty

Main method called by do of parent sequence after it generates the current


sequence. Implement this method to define the behavior of the sequence.

mid_do(s:
any_sequence_item)
is empty;

Hook method called in the middle of do, just after s is generated and
before it is executed by calling the body() TCM.

post_body() @sys.any
is empty;

Hook method called after body() when sequence is started using the
start_sequence() method.

post_do(s:
any_sequence_item)
is empty;

Hook method called at end of do, just after the execution of s.body().

post_do_tcm(s:
any_sequence_item)
@sys.any is empty;

Hook TCM called after post_do(). Extends the life of a do after the
item_done event is emitted. The sequence driver, freed by the item_done
event, no longer manages the current item. It can handle other items.

Specman e Language Reference


1999-2015

913
.

Product Version 15.1


All Rights Reserved.

Table 18-2

any_sequence Interface

Struct Member

Description

post_trace()

Gets called for every sequence just after a trace message about it gets
printed. (Useful for breakpoints.)

pre_body() @sys.any
is empty;

Hook method called before body() when sequence is started using the
start_sequence() method.

pre_do(is_item: bool)
@sys.any is empty;

Hook TCM called at start of a do performed by the sequence. is_item


specifies whether you are in a context of do-ing an item or a sequence.

18.4.1

any_sequence.grab()

Purpose
This method of any_sequence lets sequences have an exclusive control over a sequence driver.

Syntax
[sequence-exp.]grab(driver) @sys.any

Parameters
driver

A BFM sequence driver expression

Description
grab() is a blocking TCM that grants its calling sequence an exclusive access to driver. A sequence that
wants exclusivity can call grab(driver). This grants exclusive access to that sequence and its
subsequences from the moment grab() returns (perhaps, after a slight delay) until the sequence calls a
corresponding ungrab(driver). During this grabbing period, the sequence driver belongs to the
sequence. The driver drives only the items that were done by the grabbing sequence or its subsequences.
When a sequence driver belongs to a sequence, only that sequence can send items to the sequence driver.
All other sequences are blocked from sending (that is, their items remain blocked).

Notes

Virtual drivers cannot be grabbed, because they do not schedule items.

Specman e Language Reference


1999-2015

914

Product Version 15.1


All Rights Reserved.

Sequence drivers cannot be grabbed while they execute a do action on a sequence item. The grab is
granted immediately after the completion of the do action.
Exclusive control means that the sequence and all its subsequences can use the sequence driver. All
other calls are blocked until ungrab().
When grabbing a sequence driver, make sure that the is_relevant() method of the sequence that grabs
the driver returns TRUE. This averts a situation in which the driver cannot send items.
grab() is hierarchical. If a sequence s1 grabs the sequence driver and then a sequence s2 enclosed
by s1 also grabs the sequence driver, there will be no delay as long as s2 has the sequence driver
within s1. So, for example, s3 (the brother of s2) cannot access the sequence driver. Only when s2
ungrabs does s3 finally get access, but everything outside s1 is still blocked.
grab() is somewhat similar to lock(), but it is different in the following respects:

grab() is hierarchical.
grab() interacts with how items are sent.

Rerunning a driver cancels the grab. If a sequence grabbed the driver before driver.rerun() was
called, the sequence must regrab the driver. If a sequence was blocked while waiting to get the grab,
then it is released without grabbing the driver. For more information, see Resetting and Rerunning
Sequences in Creating e Testbenches.

See Also

grab_test.e in the ex_atm/examples directory (an example of grabbing and ungrabbing)

any_sequence.ungrab() on page 917

18.4.2

any_sequence.is_blocked()

Purpose
This method is valid for BFM sequences only. It indicates whether a sequence is blocked from sending
items. It happens when another sequence that is not an ancestor has grabbed the sequence driver.

Syntax
[sequence-exp.]is_blocked(): bool

Parameters
None

Specman e Language Reference


1999-2015

915
.

Product Version 15.1


All Rights Reserved.

Description
is_blocked() is a non-time-consuming method that returns TRUE if the sequence is blocked by another
sequence that grabbed the sequence driver.

See Also

any_sequence.grab() on page 914

18.4.3

any_sequence.start_sequence()

Purpose
This method of any_sequence is used to initiate the run of a sequence.

Syntax
[sequence-exp.]start_sequence()

Parameters
None

Description
start_sequence() is a non-time-consuming method that starts the body() TCM of the sequence. Use this
method instead of starting the body() TCM directly. When doing so, a new sequence tree is executed.

Notes

The start_sequence() of the MAIN sequence is called automatically by the driver.


Before calling the start_sequence() of all sequences other than the MAIN sequence, you must
generate the sequence and connect the driver to the sequence using either a constraint or procedural
code.
The parent_sequence field of a started sequence is NULL. A started sequence has no parent sequence,
because it serves as the root of a new sequence tree.

Specman e Language Reference


1999-2015

916

Product Version 15.1


All Rights Reserved.

18.4.4

any_sequence.stop()

Purpose
This method of any_sequence is used to terminate the run of a sequence.

Syntax
[sequence-exp.]stop()

Parameters
None

Description
stop() is a non-time-consuming method that terminates the execution of body() (if such exists) by
killing its thread. This might become useful if, for example, you want to terminate a sequence in the
middle upon interrupt and execute an alternative sequence instead.

Notes

Stopping a sequence also stops its containing tree. To stop only the sequences subsequence tree,
make sure that the sequence is started (not done) by its parent sequence.
Stopping is done on a cycle boundary, so some non-time-consuming actions in the stopped sequence
might still be executed after the sequence itself was stopped.

When stopping a sequence, the event stopped is emitted both for the stopped sequence and its root.

When a sequence is stopped, it and all of its subsequences are released from the grab.

For correct behavior of stop() for virtual sequences, make sure that the method get_sub_drivers()
of the virtual driver is implemented correctly and returns all BFM drivers to which the sequence and
its subsequences might send items. This is also important when stopping a BFM sequence that was
done by a virtual sequence. For more information about virtual sequences, see Using Virtual
Sequences in Creating e Testbenches.

18.4.5

any_sequence.ungrab()

Purpose
This method of any_sequence stops sequences from having an exclusive control over a sequence driver.
Specman e Language Reference
1999-2015

917
.

Product Version 15.1


All Rights Reserved.

Syntax
[sequence-exp.]ungrab(driver)

Parameters
driver

A BFM sequence driver expression

Description
ungrab() is a non-time-consuming method that releases the driver from the exclusive control of the
sequence that was previously granted by calling grab().

Notes

A virtual driver cannot be ungrabbed, because it does not schedule items.

Calling ungrab() when a sequence did not grab the driver results in error.

See Also

grab_test.e in the ex_atm/examples directory (an example of grabbing and ungrabbing)

any_sequence.grab() on page 914

18.5 any_sequence_driver
Notes

Some of the driver members are relevant only for BFM drivers, not for virtual drivers, as indicated
in the last column in Table 18-3. For more information about virtual sequences, see Using Virtual
Sequences in Creating e Testbenches.
Never use is only on the pre_generate() or post_generate() of drivers. The list of previously sent
items of the driver is initialized in the post_generate() of the driver.
Never use is only on the run() or rerun() of drivers. Some important initializations are performed
in those methods.

Specman e Language Reference


1999-2015

918

Product Version 15.1


All Rights Reserved.

Table 18-3

any_sequence_driver Interface

Struct Member

BFM
Only

Description

Read Only Member (can only be accessed)

sequence: MAIN sequence_name;

The MAIN sequence, whose body is started


automatically at the beginning of the run phase.

No

sequence is not a field of any_sequence_driver. It


is a field of the specific sequence driver type
expanded by the sequence statement.
branch_terminated()

Lets you resume normal operation in the current


cycle when a do action in a first of block
terminates prematurely. See

No

any_sequence_driver.branch_terminated() on
page 927 for more information.

current_grabber(): any_sequence

Indicates which sequence (if any) has exclusive


control over a sequence driver. See

Yes

any_sequence_driver.current_grabber() on page
925 for more information.

get_current_item():
any_sequence_item

Returns the item currently being sent. (NULL if the


BFM is currently idle.)

Yes

get_index(): int

Returns index of this sequence driver in the


all-driver list.

No

get_next_item(): item_name
@clock

This TCM should be called in PULL_MODE to


receive the next item from the BFM driver. This
TCM is blocked until there is an item to do in the
driver.

Yes

get_next_item() is not a method of


any_sequence_driver. It is a method of the
specific sequence driver type expanded by the
sequence statement.
get_num_items_sent(): int

Returns count of items sent (excluding


current_item, if any).

Specman e Language Reference


1999-2015

919
.

Yes

Product Version 15.1


All Rights Reserved.

Table 18-3

any_sequence_driver Interface

Struct Member

Description

has_do_available(): bool

Returns TRUE if the driver can execute a do


immediately. See

BFM
Only
Yes

any_sequence_driver.has_do_available() on
page 927 for more information.

is_grabbed(): bool

Indicates the grab status of the sequence driver. See

Yes

any_sequence_driver.is_grabbed() on page 924

for more information.


last(index): any_sequence_item

Enables access to previously sent items in the


sequence driver. See any_sequence_driver.last()
on page 925 for more information.

Yes

try_next_item(): item_name
@clock

This TCM should be called in PULL_MODE when


the BFM has to receive an item or perform some
default behavior. Unlike get_next_item(), in case
there is no available item waiting to be done in the
current cycle, this TCM returns NULL.

Yes

try_next_item() is not a method of


any_sequence_driver. It is a method of the
specific sequence driver type expanded by the
sequence statement.
Note try_next_item() returns in the same cycle
if there is no pending do action. However, if a do
action started execution, then try_next_item()
might take longer than a cycle, for example, if you
extend the pre_do() TCM to take longer than a
cycle.

Specman e Language Reference


1999-2015

920

Product Version 15.1


All Rights Reserved.

Table 18-3

any_sequence_driver Interface

Struct Member

BFM
Only

Description

Read/Write Member (can also be set, constrained, or implemented)

arbitration_mode:
seq_interaction_mode_t

Specifies one of the following ways the driver


chooses a do request per get_next_item() or
try_next_item():

No

FIFO (the default) Requests of the same


priority are granted in the order in which they
were registered.
RANDOM Requests of the same priority are
granted in random order.

Note

You cannot extend the


seq_arbitration_mode_t type.
Because this is a const field of a unit, its value
is determined once and for all at pre-run
generation.

bfm_interaction_mode:
bfm_interaction_mode_t

Specifies the way the driver and the BFM interact


with each other. Possible options are
PULL_MODE (the default) and PUSH_MODE. It
can be constrained.

Yes

max_random_count: int

Used in setting the maximum number of


subsequences in a RANDOM or MAIN sequence.

No

keep soft max_random_count ==


MAX_RANDOM_COUNT;
// Defined to
// be 10

max_random_depth: int

Used for setting the maximum depth inside


RANDOM sequences. (Beyond that depth,
RANDOM creates only SIMPLE sequences.)

No

keep soft max_random_depth ==


MAX_RANDOM_DEPTH;
// Defined
// to be 4

num_of_last_items: int

Used for setting the length of the history of


previously sent items. Default is 1.

Specman e Language Reference


1999-2015

921
.

Yes

Product Version 15.1


All Rights Reserved.

Table 18-3

any_sequence_driver Interface
BFM
Only

Struct Member

Description

gen_and_start_main: bool

Enable or disable automatic generation and launch


of the MAIN sequence upon run. Default is TRUE
(MAIN sequence is generated and started).

No

check_is_relevant()

For forcing a driver to recheck the relevance (value


of is_relevant()) for each sequence that has items
in the drivers item queue. It can be useful when
something has changed in the BFM that affects the
relevance of some sequences.

Yes

delay_clock() @sys.any

This TCM can be used to emit the drivers clock


with some intercycle delay to let the BFM export
its state before activation of sequences in a specific
cycle.

No

Note This TCM should be activated INSTEAD


of connecting the clock to another event.
event clock

The main clock. Should be tied to some temporal


formula by users during the sequence driver
hooking.

No

event item_done

Synchronization event for the do action in


PULL_MODE. When working in PULL_MODE,
you must emit this event to complete the do item
and let the driver get more items using
get_next_item().

Yes

See also any_sequence_driver on page 918.


get_sub_drivers(): list of
any_sequence_driver is empty

For virtual sequence drivers, this method is to be


filled in by the writer of the specific sequence
driver. It should return the list of subdrivers of the
sequence driver. For a BFM sequence driver, it
should be left unchanged, that is, return an empty
list.

Virtual
only

read(address: list of bit): list of bit


@clock is undefined;

For implementing a DUT-independent interface.

No

Specman e Language Reference


1999-2015

922

Product Version 15.1


All Rights Reserved.

Table 18-3

any_sequence_driver Interface

Struct Member

Description

BFM
Only

regenerate_data() is empty

Regenerates drivers data upon rerun().

No

See also Resetting and Rerunning Sequences in


Creating e Testbenches.
send_to_bfm(seq_item:
item_name) @clock is empty

When working in PUSH_MODE, sends the item to


the corresponding BFM. To be implemented by
users as part of hooking.

Yes

This method is called automatically (when working


in PUSH_MODE).
send_to_bfm() is not a method of
any_sequence_driver. It is a method of the
specific sequence driver type expanded by the
sequence statement.
wait_for_sequences() @sys.any

This TCM is called to delay the return of


try_next_item() and let sequences create items. It
can also be called in other locations to help
propagation of activity (for example, among
several layers of sequences). It can also be
overridden to implement a different scheme than
the default one.

Yes

write(address: list of bit, data: list


of bit) @clock is undefined;

For implementing a DUT-independent interface.

No

Sequence Item do API


any_sequence_driver.wait_for_g
rant() on page 928

Register a do-item request and wait until the request


is granted.

any_sequence_driver.deliver_ite
m() on page 929

Hand over an item to be sent to the item consumer.

any_sequence_driver.execute_it
em() on page 930

Encapsulates queue_item() and


wait_for_item_done().

any_sequence_driver.execute_it
em() on page 930

Hand over an item to be sent to the item consumer


when its turn comes.

Specman e Language Reference


1999-2015

923
.

Product Version 15.1


All Rights Reserved.

Table 18-3

any_sequence_driver Interface
BFM
Only

Struct Member

Description

any_sequence_driver.wait_for_it
em_done() on page 931

Wait for item_done acknowledgement from the


consumer.

any_sequence_driver.wait_for_n
ext_grant() on page 932

Skip the currently granted requests turn to deliver


an item and wait for its next grant.

any_sequence_driver.abort_do_r
equest() on page 933

Drop the currently granted request altogether.

18.5.1

any_sequence_driver.is_grabbed()

Purpose
This method is valid for BFM sequence drivers only. It indicates the grab status of the sequence driver.

Syntax
[driver-exp.]is_grabbed(): bool

Parameters
None

Description
is_grabbed() is a non-time-consuming method that returns TRUE if the sequence driver is grabbed by a
sequence.

See Also

any_sequence.grab() on page 914

Specman e Language Reference


1999-2015

924

Product Version 15.1


All Rights Reserved.

18.5.2

any_sequence_driver.current_grabber()

Purpose
This method is valid for BFM sequence drivers only. It indicates which sequence (if any) has exclusive
control over a sequence driver.

Syntax
[driver-exp.]current_grabber(): any_sequence

Parameters
None

Description
current_grabber() is a non-time-consuming method that returns the sequence that currently has
exclusive control over the sequence driver. It returns NULL if no sequence currently has exclusive
control over the sequence driver.

See Also

any_sequence.grab() on page 914

18.5.3

any_sequence_driver.last()

Purpose
This method is valid for BFM sequence drivers only. It enables access to previously sent items in the
sequence driver.

Syntax
[driver-exp.]last(index): item

Specman e Language Reference


1999-2015

925
.

Product Version 15.1


All Rights Reserved.

Parameters
index

The index in the sequence history. 0 is the currently sent item, 1 is the
previous item, and so on.

Return Value
item

The item that was created index items ago by the sequence. The return value
is NULL if such item does not exist.

Description
last() is a non-time-consuming method that lets you directly access items in the history of the sequence:

last(0) returns the item currently being driven in (or the last item that was driven in, if there is no
item currently being driven in).
last(1) returns the item before last(0), and so on.

The length of the history is determined by the field num_of_last_items in the sequence driver, which can
be constrained by the user. The default is 1.

Notes

last(i) results in an error if i >= num_of_last_items.

The maximum value for num_of_last_items is 1024.

num_of_last_items is a static property of the BFM driver. Therefore, it cannot be changed during the
run.

Example 1
You could create a sequence that alternates colors from red to green as follows:
extend packet {
keep color == (driver.last(0) is a GREEN packet ? RED : GREEN);
};

Example 2
You could configure the buffer to store the last 10 items (instead of the default 1 item) as follows:
extend packet_seq_driver {
keep num_of_last_items == 10
};
Specman e Language Reference
1999-2015

926

Product Version 15.1


All Rights Reserved.

Notes

The is a construct is a convenient way to also avoid checking for non-NULL.


For efficiency, in the sequence driver you might want to set Boolean flags that summarize the last()
information. In that case, the constraint can refer to the Boolean flags rather than last().

You can also use last()-based constraints in sequences (not just items).

The last() buffer is cleared upon driver.rerun().

18.5.4

any_sequence_driver.branch_terminated()

Purpose
This method of any_sequence_driver is relevant when performing a do action inside a first of block.

Syntax
[driver-exp.]branch_terminated()

Parameters
None

Description
This method lets you resume normal operation in the current cycle when a do action in a first of block
terminates prematurely.

18.5.5

any_sequence_driver.has_do_available()

Purpose
This method of any_sequence_driver tells an inquiring BFM if a do is available for execution.

Syntax
[driver_exp.]has_do_available(): bool

Specman e Language Reference


1999-2015

927
.

Product Version 15.1


All Rights Reserved.

Parameters
None

Description
This method of any_sequence_driver returns TRUE if the driver can execute a do immediately. This can
only happen when the following conditions are met:

The driver is not already busy handling a do (because the driver can only handle one do at a time).
The driver has in its queue at least one relevant do (that is, its parent sequence returns TRUE for
is_relevant()).
The relevant do is not blocked (because another sequence has grabbed the driver).

Note Even when has_do_available() returns TRUE, an item might not be returned immediately by
get_next_item(). It depends on the pre_do() TCM.

Example
...
if my_driver.has_do_available() {
var an_item := my_driver.get_next_item();
};
...

18.5.6

any_sequence_driver.wait_for_grant()

Purpose
Register a do-item request and wait until the request is granted

Method Type
Time-consuming method

Syntax
driver.wait_for_grant(seq: any_sequence) @sys.any

Specman e Language Reference


1999-2015

928

Product Version 15.1


All Rights Reserved.

Description
Registers a do-item request and waits until the request is granted. Use this TCM to synchronize with a
consume request (get/try_next_item()), so as to enable just-in-time generation. When it returns, the
driver is in a waiting-for-item state and does not go on to handle another do request until an item is
delivered, or until the grant is waived (see any_sequence_driver.wait_for_next_grant() on page 932
and any_sequence_driver.abort_do_request() on page 933).
The sequence passed as the seq parameter is considered for purposes of request scheduling, and can
affect it through grabbing and its is_relevant() callback. The seq parameter can be an object of any type
derived from any_sequence, including a virtual sequence. If NULL is passed as the seq parameter, the
default sequence is considered for scheduling purposes (never grabbing and always relevant).

See Also

Using the Sequence Item do API in Creating e Testbenches

18.5.7

any_sequence_driver.deliver_item()

Purpose
Hand over an item to be sent to the item consumer

Method Type
Regular method

Syntax
driver.deliver_item(item: any_sequence_item)

Description
Hands over an item to be sent to the item consumer. An item can be delivered only when this sequence
driver has granted a do request, and only once per request. A runtime error is issued if the method is
called while the driver is not in a waiting-for-item state.
The parameter item must be an object of a type compatible with the concrete type of this driver;
otherwise a runtime error is issued.

Specman e Language Reference


1999-2015

929
.

Product Version 15.1


All Rights Reserved.

See Also

Using the Sequence Item do AP in Creating e Testbenches

18.5.8

any_sequence_driver.execute_item()

Purpose
Hand over an item to be sent to the item consumer when its turn comes and wait for item_done
acknowledgement from the consumer

Method Type
Regular method

Syntax
driver.execute_item(item: any_sequence_item)

Description
Encapsulates two do API methods, queue_item() and wait_for_item_done(), allowing you to place
items on various sequence drivers without knowing about sequences.
The parameter item must be an object of a type compatible with the concrete type of this driver;
otherwise a runtime error is issued.

See Also

Using the Sequence Item do API in Creating e Testbenches

18.5.9

any_sequence_driver.queue_item()

Purpose
Hand over an item to be sent to the item consumer when its turn comes

Method Type
Regular method

Specman e Language Reference


1999-2015

930

Product Version 15.1


All Rights Reserved.

Syntax
driver.queue_item(seq: any_sequence, item: any_sequence_item)

Description
Hands over an item to be sent to the item consumer when its turn comes. You can use this method when
just-in-time generation of the item is not required.
The sequence passed as the seq parameter is considered for purposes of request scheduling, and can
affect it through grabbing and its is_relevant() callback. The seq parameter can be an object of any type
derived from any_sequence, including a virtual sequence. If NULL is passed as the seq parameter, the
default sequence is considered for scheduling purposes (never grabbing and always relevant).
The parameter item must be a legal object of a type compatible with the concrete type of this driver;
otherwise a runtime error is issued.
Note Because the driver keeps and passes on a reference to the same object referenced by item, any
subsequent change of state in the object referenced by item might also be seen by the consumer (BFM).
Calling this method is equivalent in behavior (but not in performance overhead) to spawning off a TCM
that waits for a do grant and delivers the item.

See Also

Using the Sequence Item do API in Creating e Testbenches

18.5.10 any_sequence_driver.wait_for_item_done()
Purpose
Wait for item_done acknowledgement from the consumer

Method Type
Time-consuming method

Syntax
driver.wait_for_item_done(item: any_sequence_item)@sys.any

Specman e Language Reference


1999-2015

931
.

Product Version 15.1


All Rights Reserved.

Description
Waits for item_done acknowledgement from the consumer. If NULL is passed as item, the call waits for
item_done notification for the last item delivered.
If the specified item is not currently pending item_done notification (in particular if it was already
acknowledged), the TCM returns immediately. Similarly, if NULL is passed as item and there is no item
pending item_done notification, the TCM returns immediately.

See Also

Using the Sequence Item do API in Creating e Testbenches

18.5.11 any_sequence_driver.wait_for_next_grant()
Purpose
Skip the currently granted requests turn to deliver an item and wait for its next grant

Method Type
TCM method

Syntax
driver.wait_for_next_grant()@sys.any

Description
Skips the currently granted requests turn to deliver an item and waits for its next grant. The request
keeps its place in the drivers do queue, and gets another chance to deliver an item when its turn comes
around. A runtime error is issued if this TCM is called while the driver is not in a waiting-for-item state.
This TCM is typically used when the sequence is unable to supply an item at the time of grant. The
driver is thus released and can attend to other do requests for the same get/try_next_item() call. In this
sense, it has the same effect as returning FALSE from the is_relevant() hook method. But relevance in
this case is determined within the body()s lexical scope and possibly in a time-consuming manner.

See Also

Using the Sequence Item do API in Creating e Testbenches

Specman e Language Reference


1999-2015

932

Product Version 15.1


All Rights Reserved.

18.5.12 any_sequence_driver.abort_do_request()
Purpose
Drop the currently granted request altogether

Method Type
Regular method

Syntax
driver.abort_do_request()

Description
Drops the currently granted request altogether. The driver is released to attend to or wait for other do
requests for the same get/try_next_item() call. A runtime error is issued if this method is called while
the driver is not in a waiting-for-item state.

See Also

Using the Sequence Item do API in Creating e Testbenches

18.6 Sequence Item do Actions


Table 18-4

Sequence Item do Actions

Action

Description

do on page 933

Do an item from inside a sequence.

do_and_grab on page 936

Do an item from inside a sequence and try to lock the


driver.

18.6.1

do

Purpose
do an item or subsequence from the body of a sequence
Specman e Language Reference
1999-2015

933
.

Product Version 15.1


All Rights Reserved.

Syntax
For regular sequences
do field-name [keeping {constraint;...}]
For virtual sequences
do [when-qualifiers] field-name [on driver-exp] [keeping {constraint;...}]

Parameters
field-name

Must be a field in the current struct. The field must have an exclamation mark
(!) in front of it and must be either a basic item or a sequence.

keeping {constraint}

Can be any constraints on the field.

Description
The do action performs the following steps:
On a subsequence

1.

Generates the field, considering the constraints, if any.

2.

Calls its body() TCM.


The do action finishes when the subsequence body() returns.

On an item

1.

Waits until the driver is ready to perform the do action.

2.

Generates the field, considering the constraints, if any.

The item is returned by get_next_item().


The do action finishes when emitting the event driver.item_done.

Virtual Sequences
When doing an item from a virtual sequence, the on driver parameter is mandatory, and a compile-time
error is issued if it is not defined. During arbitration of pending do requests, the virtual sequence is
treated by the sequence driver just like a BFM sequenceits grabbing is taken into consideration, and
its is_relevant() method is sampled.

Specman e Language Reference


1999-2015

934

Product Version 15.1


All Rights Reserved.

When doing a sequence on another BFM or virtual driver, using the on driver parameter is not required,
but it is strongly recommended. With the on driver option, the BFM subsequence is terminated
automatically when the BFM driver is rerun(), returning control back to the virtual parent sequence as
if the subsequence has finished. Without the on driver option, the BFM sequence continues executing,
even though its corresponding driver stateany outstanding do or grab requestsis reset.
The on driver parameter is never required inside BFM sequences. If supplied, the on driver parameter
must coincide with the driver reference of the doing sequence.

Notes

When do-ing an item, you must emit the event driver.item_done to let the sequence complete the
do action and inform the driver that the item was processed. (Typically, this is done when the
transmission of the item via the BFM is done.) Without emitting this event, the sequence cannot
continue, and the driver cannot drive more items.
The do action can only be activated inside sequences.
For items, Step 1 (waiting for the sequence driver to be ready) is performed before Step 2 (generation)
to ensure that generation is done as close as possible to the actual driving. In this way, if the constraints
depend on the current status of the DUT/environment, that status will be as accurate as possible.
BFM sequences cannot do sequences created by other sequence statements.
The sequence driver decides when the item is ready by managing a FIFO that also considers any
grab/ungrab actions done by the various sequences and the value of is_relevant() of the sequences.
If no grab is done, and is_relevant() returns TRUE for all sequences, the order of doing the items is
determined by the order of the do actions in the various sequences that refer to the sequence driver,
regardless of their depth or origin. Keep in mind that sequences and items can also be done in parallel,
using the all of and first of actions. (See any_sequence.grab() on page 914 and
any_sequence_item.is_relevant() on page 910.)
do is a time-consuming action encapsulating a set of actions that can be considered as an atomic
activation of an item/sequence. However, if for some reason you want to perform any of these steps
separately from the do, you can easily do so.

Example of Regular Sequences


<
extend
//
i:
b:

FOO ex_atm_sequence {
Parameters
int;
bool;

// Items/subsequences
!cell: ex_atm_cell;
!seq: bar ex_atm_sequence;

Specman e Language Reference


1999-2015

935
.

Product Version 15.1


All Rights Reserved.

// The body() method


body() @driver.clock is {
do cell keeping {.len == 4};
do cell;
for i = 1 to 20 do {
do cell keeping {.address == i};
};
do seq keeping {.f == 2};
};
};

Example of Virtual Sequences


The following code illustrates different uses of the do on syntax:
extend MIX
// ...
body()
//
do

v_seq {
@driver.clock is only {
do a frame
BIG frame on driver.p_frame_drvr;

// do a packet with constraints


do packet on driver.p_packet_drvr keeping {it.data == 0xfff0};
// do a BFM sequence on a driver reference obtained from a method
do SHORT packet_seq on sys.get_some_packet_driver();
// do a virtual sequence on another virtual driver
do sub_v_seq on sys.another_v_drvr keeping {it.kind != RESET};
};
};

18.6.2

do_and_grab

Purpose
This action executes a do action and a grab() method simultaneously.

Syntax
do_and_grab field_name [keeping {constraint;...}]

Specman e Language Reference


1999-2015

936

Product Version 15.1


All Rights Reserved.

Parameters
field_name

Must be a non-generatable basic item in the current struct. In other words, the
field represents a sequence item and not a sequence.

keeping {constraint}

Can be any constraints on the field.

Description
The do_and_grab action differs from a normal do action in that it also grabs the do-ing sequences
driver.
The do_and_grab action differs from a regular grab() as follows. When a regular grab() occurs, the
attempt to lock the driver is immediate. With do_and_grab, no grabbing is attempted until the driver
starts handling the item.

Notes

If get_next_item() terminates before returning the item done by do_and_grab, the grab still takes
effect.

Example
...
do_and_grab my_item;
do my_item keeping {.x==BLUE;};
do another_item;
ungrab(driver);
...

See Also

do on page 933

any_sequence.grab() on page 914

18.7 Pseudo-Routines for Tree Constraints


These routines let you enforce constraints on every item created inside a specific sequence (a sequence
tree) or inside a specific unit (a unit instance tree).

Specman e Language Reference


1999-2015

937
.

Product Version 15.1


All Rights Reserved.

Table 18-5

Sequence-Related Pseudo-Routines

Routine

Description

in_sequence() on page 938

Returns TRUE if exp is an item or a sequence that was created using


do inside a sequence of a specified type.

in_unit() on page 939

Returns TRUE if you are inside a specified unit instance or unit type.

18.7.1

in_sequence()

This pseudo-routine can be used inside sequences and items.

Syntax
[exp.]in_sequence(sequence_type) [(name)]

Parameters
exp

An item, sequence, or a BFM sequence driver expression. If exp is missing,


me is used.

sequence_type

Any type or subtype of a sequence (that is, it inherits from any_sequence).

name

Reference for the found sequence.

Description
The in_sequence() routine returns TRUE if exp is an item or a sequence that was created using do inside
a sequence of type sequence_type (at any depth). If name is specified, it assigns the found sequence to
name.
If exp is a BFM sequence driver sd, then in_sequence() returns TRUE if sd.last(0) returns TRUE.
in_sequence() can be used in constraints to determine whether an item is inside a specific sequence
type. This allows enforcing constraints on every item in the sequence tree under a specific sequence.
Therefore, this kind of constraint is called a tree constraint. It is useful when you want to say something
like:
Every ATM cell under the FOO sequence should be green, regardless of how far down it is in the
hierarchy.

Specman e Language Reference


1999-2015

938

Product Version 15.1


All Rights Reserved.

Example
<'
extend ex_atm_cell {
keep in_sequence(FOO ex_atm_sequence) => color == GREEN;
// Implements the condition above
keep in_sequence(BAR ex_atm_sequence) (B) => len == B.len1;
// If this cell is somewhere under a BAR ex_atm_sequence,
// then set len to this sequence's len1 field
};
'>

Of course, the in_sequence() pseudo-routine can also be used in normal procedural code. For example:
if in_sequence(BAR ex_atm_sequence) (B) then {
print B.len1;
};

18.7.2

in_unit()

Syntax
[exp.]in_unit(unit_type) [(name)]

Parameters
exp

A struct. If exp is missing, me is used.

unit_type

Any type or subtype of a unit.

name

Reference for the found unit.

Description
in_unit() returns TRUE if you are inside such a unit (at any depth). If name is specified, it assigns the
found unit to name.

Note

This pseudo-routine can be used anywhere.


in_unit(foo) is equal to: try_enclosing_unit(foo) != NULL. The motivation behind this routine is
to make it shorter and similar to in_sequence() as well as to enable tree constraints.

Specman e Language Reference


1999-2015

939
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

940

Product Version 15.1


All Rights Reserved.

19

Messaging Interface

This chapter contains the following sections:

Actions for Defining Structured Debug Messages (SDMs) on page 941

Actions for Defining Regular Messages on page 955

Predefined Types Related To Messaging on page 958

Methods for Modifying Message Settings (via message_manager) on page 966

Method for User-Defined Message Formatting on page 978

recording_config API on page 982

Messaging Interfaces Under Deprecation on page 1006

Note Logger-based messaging is being deprecated over time and is being replaced with a messaging
system that does not use loggers. However, because message loggers continue to be supported until fully
deprecated, a description of the messaging interface features related to message loggers is provided in
Messaging Interfaces Under Deprecation on page 1006. At some point, in a future release, these
features will not be supported.

19.1 Actions for Defining Structured Debug


Messages (SDMs)
The following message actions create structured debug messages:

msg_started() on page 942

msg_ended() on page 944

msg_transformed() on page 948

msg_changed() on page 950

msg_info() on page 953

Specman e Language Reference


1999-2015

941
.

Product Version 15.1


All Rights Reserved.

See Also

Actions for Defining Regular Messages on page 955

Predefined Types Related To Messaging on page 958

Methods for Modifying Message Settings (via message_manager) on page 966

Method for User-Defined Message Formatting on page 978

recording_config API on page 982

19.1.1

msg_started()

Purpose
Reports the start of a new transaction.

Category
Action

Syntax
msg_started([tag,]verbosity, msg-id, data-item) [{action-block}]
Syntax Example
msg_started(LOW, "monitoring burst", driven_burst);

Parameters
tag

Optional identifier used to direct the output (for example, to a file). Default is NORMAL
(which is the only predefined message tag type). Before a non-predefined message tag can be
used in a message action, the tag must already have been defined by extending the
message_tag type. For more information, see message_tag on page 959.

verbosity

Specifies how often a message will be printed. Values and suggested usage:
NONE: Messages that cannot be disabled
LOW: Once per run (reset messages, and so on)
MEDIUM: Once per transaction
HIGH: More detailed
FULL: All the details
See Defining Message Verbosity in Creating e Testbenches for more information.

Specman e Language Reference


1999-2015

942

Product Version 15.1


All Rights Reserved.

msg-id

The message ID. A string expression that identifies the specific occurrence reported by the
message:

When a literal string is provided (as opposed to a string expression that is computed at
runtime), the text can be used for static message filtering.
When displayed in the Waveform window or Stripe Chart Viewer, the id string serves to
identify the waveform fiber.

data-item The struct that contains the data that is being processed.
actionblock

A list of zero or more actions separated by semicolons and enclosed in curly braces.
Syntax: {action;...}
A pseudo variable called it automatically references the sdm_handler object (see
sdm_handler on page 963) representing the current message. You can optionally assign the

it fields described below inside the action-block. Example:


msg_started(HIGH," monitoring transfer",cur_trans) {
it.parent = cur_burst;
};

(Note, however, that you can use this action-block like any action-block in e .)
The action-block is executed once if the message action is not discarded due to filtering.
scope

Identifies the unit context where transaction tracking is to start. This can be used,
for example, to hide the actual unit and use an enclosing unit as the message
scope.
The default is me if the message is issued within the scope of a unit type.
Otherwise, the default is the value returned from it.

body-text Defines a text string, or a list of text strings separated by commas, to be displayed
with the message. Use this field to override the messages default text, which is a
hyperlink to the logged transaction.
parent

Identifies the higher-level (parent) transaction containing the current transaction.


If specified, the struct assigned to the .parent field becomes the parent transaction,
and the data item of the current transaction becomes the child transaction.
This can be useful, for example, for showing to which burst a set of packets
belongs. (Transactions are usually used to model packets, and bursts are the
children of transfers; thus, the parent attribute for each packet points to the
burst message, and parent of the burst points to a transfer.)

Description
Code a msg_started() action at the beginning of each transaction that you want to track.
The standard form of a message for this message action is:
Specman e Language Reference
1999-2015

943
.

Product Version 15.1


All Rights Reserved.

(started - msg-id) data-item

The configurable message instance parameters in the action block are fields of the message handler
struct for the message action. You can set these fields by referring to them as it.field.
When transaction recording is enabled, you can view each transaction graphically in the Waveform
window and Stripe Chart Viewer. Attributes of the transaction are registered by using the recording
configuration, described in recording_config API on page 982.

Example
The following message reports the beginning of a transfer reading by a monitor.
msg_started(HIGH," monitoring transfer",cur_trans)
{ it.parent = cur_burst };

This message is output in one line as follows, when using short formatting and short names
(my_evc_...@338 is the hyperlink to the logged transaction):
[63400] ENV_0 M0 MON: (started - monitoring transfer)
my_evc_monitor_transfer-@338

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

msg_ended() on page 944

msg_transformed() on page 948

msg_changed() on page 950

msg_info() on page 953

Defining Structured Debug Message Actions in Creating e Testbenches

19.1.2

msg_ended()

Purpose
Reports the end of processing for a given transaction.

Category
Action

Specman e Language Reference


1999-2015

944

Product Version 15.1


All Rights Reserved.

Syntax
msg_ended([tag,] verbosity, msg-id, data-item) [{action-block}]
Syntax Example
msg_ended(HIGH,"monitoring transfer",cur_trans);

Parameters
tag

Optional identifier used to direct the output (for example, to a file). Default is NORMAL
(which is the only predefined message tag type). Before a non-predefined message tag can
be used in a message action, the tag must already have been defined by extending the
message_tag type. For more information, see message_tag on page 959.

verbosity

Specifies how often a message will be printed. Values and suggested usage:
NONE: Messages that cannot be disabled
LOW: Once per run (reset messages, and so on)
MEDIUM: Once per transaction
HIGH: More detailed
FULL: All the details
See Defining Message Verbosity in Creating e Testbenches for more information.

msg-id

The message ID. A string expression that identifies the specific occurrence, or transaction
stream, reported by the message.
If a corresponding msg_started() action exists, this expression must be the same as the
msg-id defined for msg_started() in order to outline the duration of the transaction.

data-item The struct that contains the data that is being processed.

Specman e Language Reference


1999-2015

945
.

Product Version 15.1


All Rights Reserved.

actionblock

A list of zero or more actions separated by semicolons and enclosed in curly braces.
Syntax: {action;...}
A pseudo variable called it automatically references the sdm_handler object (see
sdm_handler on page 963) representing the current message. You can optionally assign the

it fields described below inside the action-block. Example:


msg_ended(HIGH," monitoring transfer",cur_trans) {
it.parent = cur_burst;
};

(Note, however, that you can use this action-block like any action-block in e .)
The action-block is executed once if the message action is not discarded due to filtering.
scope

Identifies the unit context where the action occurs. This can be used, for example,
to hide the actual unit and use an enclosing unit as the message scope.
The default is me if the message is issued within the scope of a unit type.
Otherwise, the default is the value returned from it.

body-text Defines a text string, or a list of text strings separated by commas, to be displayed
with the message. Use this field to override the messages default text, which is a
hyperlink to the logged transaction.
start-time The time at which this transaction started (by default UNDEF, which indicates
that the starting of the transaction was already reported by a msg_started()
action). Must be a value of type time.
parent

Identifies the higher-level (parent) transaction containing the current transaction.


If specified, the struct assigned to the .parent field becomes the parent transaction,
and the data item of the current transaction becomes the child transaction.
Use this optional parameter only when there is no corresponding msg_started()
action. In this case, msg_ended() should also specify the transaction start_time.
This parameter can be useful, for example, for showing to which burst a set of
packets belongs. (Transactions are usually used to model packets, and bursts are
the children of transfers; thus, the parent attribute for each packet points to the
burst message, and parent of the burst points to a transfer.)

Description
Reports the end of each transaction that you want to track. Unless you specify the sample points with the
recording configuration API, data is sampled as follows:

When a msg_ended() action has a corresponding msg_started() action, data is sampled at both the
beginning and end of the transaction.

Specman e Language Reference


1999-2015

946

Product Version 15.1


All Rights Reserved.

When a msg_ended() action has no corresponding msg_started() action, you can specify the start
time in the body of the msg_ended() action. In this case, data is sampled at the end of the transaction.
When a msg_ended() action has no corresponding msg_started() action, and no start time is set in
the action body, a 0-time transaction is created, and data is sampled at the end of the transaction.

When transaction recording is enabled, you can view each transaction graphically in the Waveform
window and Stripe Chart Viewer. Attributes of the transaction are registered by using the recording
configuration, described in recording_config API on page 982.
The standard form of a message for this message action is:
(ended - msg-id) data-item

The configurable message instance parameters in the action block are fields of the message handler
struct for the message action. You can set these fields by referring to them as it.field.

Example
The following action identifies the end of transfer reading by a monitor.
msg_ended(HIGH,"monitoring transfer",cur_trans);

This message is output as follows when using short formatting and short path names:
[65500] ENV_0 MON: (ended - monitoring transfer)
my_evc_monitor_transfer-@347

The message also reports on attribute sampling, specified with the recording configuration API. You can
use the recording configuration API to control the set of attributes and state variables that are recorded
in the simulation database.

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

msg_started() on page 942

msg_transformed() on page 948

msg_changed() on page 950

msg_info() on page 953

Defining Structured Debug Message Actions in Creating e Testbenches

Specman e Language Reference


1999-2015

947
.

Product Version 15.1


All Rights Reserved.

19.1.3

msg_transformed()

Purpose
Reports the transformation of an existing data item or items, or the outcome of a relationship between
data items.

Category
Action

Syntax
msg_transformed([tag,] verbosity, msg-id, from-item, to-item) [{action-block}]
Syntax Example
msg_transformed(HIGH,"scoreboard match",add_pkt,match_pkt);

Parameters
tag

Optional identifier used to direct the output (for example, to a file). Default is NORMAL
(which is the only predefined message tag type). Before a non-predefined message tag can be
used in a message action, the tag must already have been defined by extending the
message_tag type. For more information, see message_tag on page 959.

verbosity

Specifies how often a message will be printed. Values and suggested usage:
NONE: Messages that cannot be disabled
LOW: Once per run (reset messages, and so on)
MEDIUM: Once per transaction
HIGH: More detailed
FULL: All the details
See Defining Message Verbosity in Creating e Testbenches for more information.

msg-id

The message ID. A string expression that identifies the specific occurrence reported by the
message.

from-item The struct containing the data that is being processed.


to-item

The struct containing the data after transformation.

Specman e Language Reference


1999-2015

948

Product Version 15.1


All Rights Reserved.

actionblock

A list of zero or more actions separated by semicolons and enclosed in curly braces.
Syntax: {action;...}
A pseudo variable called it automatically references the sdm_handler object (see
sdm_handler on page 963) representing the current message. You can optionally assign the

it fields described below inside the action-block. Example:


msg_transformed(MY_TAG, MEDIUM,"Matching bursts",exp_i,m) {
it.body_text = appendf("Successful match\n
burst_type: %s \n
start_addr: %d \n",
m.burst_type, m.start_addr);
};

(Note, however, that you can use this action-block like any action-block in e .)
The action-block is executed once if the message action is not discarded due to filtering.
scope

Identifies the unit context where the action occurs. This can be used, for example,
to hide the actual unit and use an enclosing unit as the message scope.
The default is me if the message is issued within the scope of a unit type.
Otherwise, the default is the value returned from it.

body-text Defines a text string, or a list of text strings separated by commas, to be displayed
with the message. Use this field to override the messages default text.

Description
You can use this action to track various kinds of data transformations and relationships:

One data item can be split into multiple items.

Multiple data items can be joined to form one item.

The subtype of transformed item(s) can be different from that of the original item.

The two items can be related in other ways, for example, when two items in the UVM scoreboard
match or when a monitored item matches its source (the item created and injected by the BFM).

Such transformations and relationships are notified by multiple calls to msg_transformed() with the
same from-item parameter and different to-item parameter (or vice versa).
Note

Use the msg-id to identify the exact nature of the transformation or relationship.

The standard form of a message for this message action is:


(transformed - msg-id) from from-item to to-item

The configurable message instance parameters in the action block are fields of the message handler
struct for the message action. You can set these fields by referring to them as it.field.
Specman e Language Reference
1999-2015

949
.

Product Version 15.1


All Rights Reserved.

Example 1
The following action identifies a scoreboard match.
msg_transformed(HIGH,"scoreboard match",add_pkt,match_pkt);

An output example of this message with short formatting (all in one line):
[543] cenv_scoreboard-@13: (transformed - scoreboard match)
from cdn_usb_packet-@29 to cdn_usb_packet-@35

Example 2
This following action identifies the creation of a higher layer item, a burst, from a list of several frames.
msg_tranformed(HIGH, "building burst out of frames", cur_frame, cur_burst);

An output example of this message with short formatting (all in one line):
[543] monitor-@8: (transformed - building burst out of frames) from
frame-@37 to burst-@72

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

msg_started() on page 942

msg_ended() on page 944

msg_changed() on page 950

msg_info() on page 953

Defining Structured Debug Message Actions in Creating e Testbenches

19.1.4

msg_changed()

Purpose
Reports a significant state change taking place in this scope.

Category
Action

Specman e Language Reference


1999-2015

950

Product Version 15.1


All Rights Reserved.

Syntax
msg_changed([tag,] verbosity, msg-id, new-state-exp) [{action-block}]
Syntax Example
msg_changed(HIGH,"transmit-state","idle");

Parameters
tag

Optional identifier used to direct the output (for example, to a file). Default is NORMAL
(which is the only predefined message tag type). Before a non-predefined message tag can be
used in a message action, the tag must already have been defined by extending the
message_tag type. For more information, see message_tag on page 959.

verbosity

Specifies how often a message will be printed. Values and suggested usage:
NONE: Messages that cannot be disabled
LOW: Once per run (reset messages, and so on)
MEDIUM: Once per transaction
HIGH: More detailed
FULL: All the details
See Defining Message Verbosity in Creating e Testbenches for more information.

msg-id

The message ID. A string expression that identifies the specific occurrence, or transaction
stream, reported by the message.

new-state- A text string describing the new state this unit assumes.
exp

Specman e Language Reference


1999-2015

951
.

Product Version 15.1


All Rights Reserved.

actionblock

A list of zero or more actions separated by semicolons and enclosed in curly braces.
Syntax: {action;...}
A pseudo variable called it automatically references the sdm_handler object (see
sdm_handler on page 963) representing the current message. You can optionally assign the

it fields described below inside the action-block. Example:


msg_changed(HIGH,"transmit-state","idle") {
.body_text = " back to idle because of no response";
};

(Note, however, that you can use this action-block like any action-block in e .)
The action-block is executed once if the message action is not discarded due to filtering.
scope

Identifies the unit context where the action occurs. This can be used, for example,
to hide the actual unit and use an enclosing unit as the message scope.
The default is me if the message is issued within the scope of a unit type.
Otherwise, the default is the value returned from it.

body-text Defines a text string, or a list of text strings separated by commas, to be displayed
with the message. Use this field to override the messages default text.

Description
Marks a change to an object, such as a state variable changing from transmit to idle. You can register
state variables and their values by using the recording configuration API.
The standard form of a message for this message action is:
(changed - msg-id) new state is new-state-exp

The configurable message instance parameters in the action block are fields of the message handler
struct for the message action. You can set these fields by referring to them as it.field.

Example
The following identifies the change of the transmitting state to idle in this BFM unit.
msg_changed(HIGH,"transmit-state","idle");

An output example of this message with short formatting and use of state variable sampling specified
through the recording config API (all in one line):
[1550] cdn_xbus_slave bfm-@2: (changed - transmit-state)
new state is 'idle' {prev_response = OK}

Specman e Language Reference


1999-2015

952

Product Version 15.1


All Rights Reserved.

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

msg_started() on page 942

msg_ended() on page 944

msg_transformed() on page 948

msg_info() on page 953

recording_config API on page 982

Defining Structured Debug Message Actions in Creating e Testbenches

19.1.5

msg_info()

Purpose
Reports a significant event in the environment, that occurs at a certain point in time, possibly related to
the provided data items or items, and which is not applicable to the other kinds of structured debug
messages.

Category
Action

Syntax
msg_info([tag,]verbosity, msg-id, [data-item1 [, data-item2]]) [{action-block}]
Syntax Example
msg_info(MEDIUM, Item dropped, pending_item[index]);

Parameters
tag

Optional identifier used to direct the output (for example, to a file). Default is NORMAL
(which is the only predefined message tag type). Before a non-predefined message tag can be
used in a message action, the tag must already have been defined by extending the
message_tag type. For more information, see message_tag on page 959.

Specman e Language Reference


1999-2015

953
.

Product Version 15.1


All Rights Reserved.

verbosity

Specifies how often a message will be printed. Values and suggested usage:
NONE: Messages that cannot be disabled
LOW: Once per run (reset messages, and so on)
MEDIUM: Once per transaction
HIGH: More detailed
FULL: All the details
See Defining Message Verbosity in Creating e Testbenches for more information.

msg-id

The message ID. A string expression that identifies the specific occurrence reported by the
message.

data-item1 References to data items involved in the reported event. You can specify up to two data items
data-item2 (both are optional).
actionblock

A list of zero or more actions separated by semicolons and enclosed in curly braces.
Syntax: {action;...}
A pseudo variable called it automatically references the sdm_handler object (see
sdm_handler on page 963) representing the current message. You can optionally assign the

it fields described below inside the action-block. Example: :


msg_info(HIGH, "Removing an item from DUT buffer", cur_frame) {
it.body_text = append("I remove the item addressed to ",
cur_frame.address, " and its data is ", cur_frame.data);
};

(Note, however, that you can use this action-block like any action-block in e .)
The action-block is executed once if the message action is not discarded due to filtering.
data-item The struct containing the data that is being processed.
scope

Identifies the unit context where the action occurs. This can be used, for example,
to hide the actual unit and use an enclosing unit as the message scope.
The default is me if the message is issued within the scope of a unit type.
Otherwise, the default is the value returned from it.

body-text Defines a text string, or a list of text strings separated by commas, to be displayed
with the message. Use this field to override the messages default text, which is a
hyperlink to the logged transaction.

Description
The standard form of a message for this message action is:
(info - msg-id) data-item1 data-item2

Specman e Language Reference


1999-2015

954

Product Version 15.1


All Rights Reserved.

The configurable message instance parameters in the action block are fields of the message handler
struct for the message action. You can set these fields by referring to them as it.field.

Example
The following example uses msg_info() to display an information message when an item is dropped:
extend my_scoreboard {
drop_pending_item(index: int) is {
msg_info(MEDIUM, Item dropped, pending_item[index]);
pending_items.delete(index);
};
};

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

msg_started() on page 942

msg_ended() on page 944

msg_transformed() on page 948

msg_changed() on page 950

Defining Structured Debug Message Actions in Creating e Testbenches

19.2 Actions for Defining Regular Messages


You create regular messages by calling the message() and messagef() actions.

message() and messagef() on page 956

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

Predefined Types Related To Messaging on page 958

Methods for Modifying Message Settings (via message_manager) on page 966

Method for User-Defined Message Formatting on page 978

recording_config API on page 982

Specman e Language Reference


1999-2015

955
.

Product Version 15.1


All Rights Reserved.

19.2.1

message() and messagef()

Purpose
Creates regular messages.

Category
Action

Syntax
message([tag], verbosity, body-text, ) [{action-block}]
messagef([tag], verbosity, body-text, ) [{action-block}]
Syntax Examples
message(LOW, "Bus ", bus_num, " is done with reset");
messagef(MEDIUM, "Packet number %d has arrived\n", packet_num);

Parameters
tag

Optional identifier used to direct the output (for example, to a file). Default is NORMAL
(which is the only predefined message tag type). Before a non-predefined message tag can
be used in a message_action, the tag must already have been defined by extending the
message_tag type. For more information, see message_tag on page 959.

verbosity

Specifies how often a message will be printed. Suggested use:


NONE: Messages that cannot be disabled
LOW: Once per run (reset messages, and so on)
MEDIUM: Once per transaction
HIGH: More detailed
FULL: All the details
See Defining Message Verbosity in Creating e Testbenches for more information.

body-text

The message to be output. When calling messagef(), the body-text can contain format
strings, such as: %d, %x, %s. For more information, see Format String on page 1528.

Specman e Language Reference


1999-2015

956

Product Version 15.1


All Rights Reserved.

action-block The action to take when a message is executed, including output-producing actions or
method calls. Example:
message(HIGH, "Master ", me, " received packet:"){
print the_packet;
};

Description
Defines regular messages and outputs them when the action is executed.
How Message Actions are Handled
When a message() or messagef() action is executed, the following happens:

For message(), the first string in the message is created by appending all of the expressions, similar
to out(). For messagef(), the first string is created using the format-exp, similar to outf().
messagef() does not automatically add a carriage return (\n) between the message and the optional
action-block. Therefore, if there is an action-block and a carriage return is required before it, end the
format-exp with \n.
If the whole messagef() output (including the optional action-block) does not end with a \n, then an
extra \n is automatically added.
messagef() also allows appending of the action-block output to the messagef() header output. For
example:
messagef(HIGH, "And the winner is: ") {
if winner != NULL then {
out(winner.name);
} else {
out("Nobody");
};
};

If an action-block exists, it gets executed. It usually contains further output-producing actions, calls
to reporting methods, and so on. The output of all of those is added as a list of string to the message.
Message code should not modify the flow of the simulation in any way. Therefore, time-consuming
operations in message headers or action blocks are not allowed.

Examples of the Message Action


message(LOW, "Bus ", bus_num, " is done with reset");
-- Output this message at verbosity LOW.
messagef(MEDIUM, "Packet number %d has arrived\n", packet_num);
Specman e Language Reference
1999-2015

957
.

Product Version 15.1


All Rights Reserved.

-- Output this message using a format string, at verbosity MEDIUM.


message(HIGH, "Master ", me, " has received ", the_packet) {
print the_packet;
};
-- Output this message and print the packet, at verbosity HIGH.
message(VR_XBUS_FILE, MEDIUM, "Packet ", num, " sent: ", data);
-- Output this message at verbosity MEDIUM.
-- Use VR_XBUS_FILE as the message-tag.

See Also

Actions for Defining Regular Messages on page 955

Defining Message Actions in Creating e Testbenches

Message Commands in Specman Command Reference

19.3 Predefined Types Related To Messaging


This section describes the following predefined types that are relevant for messaging.

message_tag on page 959

message_manager on page 959

message_format on page 960

message_action on page 961

sdm_handler on page 963

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

Actions for Defining Regular Messages on page 955

Methods for Modifying Message Settings (via message_manager) on page 966

Method for User-Defined Message Formatting on page 978

recording_config API on page 982

Specman e Language Reference


1999-2015

958

Product Version 15.1


All Rights Reserved.

19.3.1

message_tag

Purpose
Used for defining tags that are used in message actions.

Category
Type

Description
The predefined type message_tag is used in message actions. It has one predefined value: NORMAL.
(For information on message actions, see Actions for Defining Structured Debug Messages (SDMs) on
page 941 and Actions for Defining Regular Messages on page 955.)
Before you can use a non-predefined message tag in a message_action, the tag needs to have already
been defined by extending the message_tag type. You extend this type using the following format (note
that multiple new name tags can be separated by commas):
extend message_tag: [name_of_new_tag,...];

Example:
extend message_tag: [MY_TAG];

See Also

Predefined Types Related To Messaging on page 958

message_manager on page 959

message_format on page 960

message_action on page 961

sdm_handler on page 963

19.3.2

message_manager

Purpose
Contains methods that are used for modifying message settings and formats.

Specman e Language Reference


1999-2015

959
.

Product Version 15.1


All Rights Reserved.

Category
Type

Description
The following predefined methods belong to the message_manager type.

set_screen_messages | set_screen_messages_off on page 966

set_transaction_messages | set_transaction_messages_off on page 969

set_file_messages | set_file_messages_off on page 971

set_message_format() on page 974

set_message_style() on page 975

See Also

Predefined Types Related To Messaging on page 958

message_tag on page 959

message_format on page 960

message_action on page 961

sdm_handler on page 963

19.3.3

message_format

Purpose
Used for defining message formats.

Category
Type

Description
Values defined using message_format can then be used for setting message formats. You can apply
these values in any of the following ways:

with a set message -format command (for more information, see set message -format in Specman
Command Reference).

Specman e Language Reference


1999-2015

960

Product Version 15.1


All Rights Reserved.

with the set_message_format() method (for more information, see set_message_format() on page
974).
with the create_formatted_message() method. In this case, notice that message_format is one of
the properties of message_action, and is returned by its get_format() method. (For more information,
see message_action on page 961 and create_formatted_message() on page 979.)

message_format has three predefined value: short, long, and none.


To introduce a new message format, you extend the message_format type, and then extend this method
to implement the custom formatting. The format for extending message_format is (note that multiple
new formats can be separated by commas):
extend message_format: [name_of_new_format,...];

For example:
extend message_format: [my_format];

Note Extending message_format (that is, introducing a new message format), is useful only if you
are extending create_formatted_message.

See Also

Predefined Types Related To Messaging on page 958

message_tag on page 959

message_manager on page 959

message_action on page 961

sdm_handler on page 963

19.3.4

message_action

Purpose
Represents a given instance of a message action.

Category
Type

Predefined Methods of message_action


The following table describes the predefined methods of message_action.
Specman e Language Reference
1999-2015

961
.

Product Version 15.1


All Rights Reserved.

Table 19-1

Methods of type message_action

Method

Description

get_id()

Returns the unique number identifying this message action.

get_tag()

Returns the tag of this message.

get_verbosity()

Returns the verbosity of this message.

get_source_method_layer()

Returns the method layer in which this message action resides.

get_source_line_num()

Returns the line number in which this message action resides.

get_style()

Returns the current style setting for this message.

get_source_struct()

Returns the actual struct instance that issued the message.

get_time()

Returns a properly formatted string for the current value of


sys.time.

get_format()

Returns the format being used for this message.

get_sdm_handler()

Returns the SDM handler which represents the SDM specific


information about the current message. (If the current message
is a regular message, it returns a NULL.)

Description
The instances of this type represent message actions that occur at run time. They provide information on
the message action through the methods described above. It is useful when you extend the predefined
create_formatted_message() method.

See Also

Predefined Types Related To Messaging on page 958

message_tag on page 959

message_manager on page 959

message_format on page 960

sdm_handler on page 963

Specman e Language Reference


1999-2015

962

Product Version 15.1


All Rights Reserved.

19.3.5

sdm_handler

Purpose
Used for providing SDM-specific information about the current message.

Category
Type

Description
The sdm_handler struct type, which belongs to the messages package, has several sub-classes for each
SDM kind.
The following members defined directly in sdm_handler, are common to all SDM kinds:
struct sdm_handler like base_struct {
scope: any_unit;
id_str: string;
body_text: string;
get_kind_string(): string;
get_attribute_string(inst: any_struct): string;
collect_text_attributes(inst: any_struct,
names: list of string, values: list of string);
};

scope Unit instance to which the message belongs (the same unit instance on which
create_formatted_message() is being called). Default: The unit in the context of which the message
is executed; this can be modified in the message's optional action block.
id_str msg-id string, as specified in the SDM action.
body_text Text assigned by the user in the optional action block (or an empty string if none isa
assigned).
get_kind_string() Returns the string representing the SDM kind. For example, "started" for
msg_started, "changed" for msg_changed.
get_attribute_string() Returns the string that displays the registered text attributes for the
specified data object (or an empty string if there are no test attributes) after registering them. Text
attributes are those for which set_text_attribute() was called (or in case of msg_changed,
set_text_state_var() was called).

Specman e Language Reference


1999-2015

963
.

Product Version 15.1


All Rights Reserved.

collect_text_attributes() Collects the names and printed string values of the registered text
attributes for the specified data object, and adds them to the two provided lists, names and values
respectively. (Both lists are cleaned before collecting attributes, and any items present in them prior
to calling this method are removed.)

The following sdm_handler sub-classes are specific to specific SDM kinds:

msg_started:
struct sdm_started_handler like sdm_handler {
data_item: any_struct;
parent: any_struct;
};

data_item Data item object specified in the msg_started() action.

parent Parent transaction object specified in the optional action block, or NULL if none.

msg_ended:
struct sdm_ended_handler like sdm_handler {
data_item: any_struct;
parent: any_struct;
start_time: time;
};

data_item Data item object specified in the msg_ended() action.

parent Parent transaction object specified in the optional action block, or NULL if none.

start_time Start time specified in the optional action block, or UNDEF if none.

msg_transformed:
struct sdm_transformed_handler like sdm_handler {
from_item: any_struct;
to_item: any_struct;
};

from_item First data item object specified in the msg_transformed() action.

to_item Second data item object specified in the msg_transformed() action.

msg_changed:
struct sdm_changed_handler like sdm_handler {
new_state: string;
};

new_state State string specified in the msg_changed() action.

msg_info:
struct sdm_info_handler like sdm_handler {
item1: any_struct;

Specman e Language Reference


1999-2015

964

Product Version 15.1


All Rights Reserved.

item2: any_struct;
};

item1 First data item object specified in the msg_transformed() action. Default (i.e., if none
specified): NULL
item2 Second data item object specified in the msg_transformed() action. Default (i.e., if
none specified): NULL

For more information on the above message actions, see Actions for Defining Structured Debug
Messages (SDMs) on page 941.

Example
Assume we have a special printing format, in which we want to print msg_started() messages in a
special form, which prints a phrase that includes the current time and the name of the type to which the
data item belongs.
extend any_unit {
create_formatted_message(action: message_action, buffer: list of
string) is first {
if action.get_format() == special and
action.get_sdm_handler() is a sdm_started_handler (sh) then {
var type_name: string =
rf_manager.get_struct_of_instance(sh.data_item).get_name();
buffer[0] = appendf(
"A transaction is started at time %s on a %s",
action.get_time(), type_name);
return;
};
};
};

If a transaction is started at time 50, with a data item of type "packet", a message with the above
formatting will look as follows:
A transaction is started at time 50 on a packet

See Also

Predefined Types Related To Messaging on page 958

message_tag on page 959

message_manager on page 959

message_format on page 960

message_action on page 961

Specman e Language Reference


1999-2015

965
.

Product Version 15.1


All Rights Reserved.

19.4 Methods for Modifying Message Settings (via


message_manager)
These methods belong to the message_manager predefined type. These methods can be categorized as
follows according to their purpose:

Methods for Modifying Message Selection on page 966

Method for modifying message characteristics on page 973

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

Actions for Defining Regular Messages on page 955

Predefined Types Related To Messaging on page 958

Method for User-Defined Message Formatting on page 978

recording_config API on page 982

19.4.1

Methods for Modifying Message Selection

The following methods modify message selection criteria, which in turn determine destination:

set_screen_messages | set_screen_messages_off on page 966

set_transaction_messages | set_transaction_messages_off on page 969

set_file_messages | set_file_messages_off on page 971

See Also

Methods for Modifying Message Settings (via message_manager) on page 966

Method for modifying message characteristics on page 973

19.4.1.1 set_screen_messages | set_screen_messages_off


Purpose
Modifies the selection of messages issued by a given unit to a screen.

Specman e Language Reference


1999-2015

966

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
set_screen_messages (
root-unit: any_unit,
tag: message_tag,
verbosity: message_verbosity
[, modules: string [, text-pattern: string [, rec: bool]]]
)
set_screen_messages_off (
root-unit: any_unit,
tag: message_tag
[, rec: bool]
)
Syntax Examples
message_manager.set_screen_messages(me.the_agent.the_monitor, NORMAL, HIGH);
message_manager.set_screen_messages_off(me, NORMAL);

Parameters
m

root-unit

Unit to which the new setting will be applied.

tag

Message tag to which the new setting applies. The new setting will only affect
messages of the specified tag.

verbosity

Highest verbosity level for messages. A given message is issued to the screen only
if its verbosity is equal to or lower than the specified verbosity.
Valid values are: NONE, LOW, MEDIUM, HIGH, and FULL.

modules

String pattern used for matching module names (wild cards permitted). A given
message is issued to the screen only if it is defined in the specified module(s).
Default value is * which matches any module name.

Specman e Language Reference


1999-2015

967
.

Product Version 15.1


All Rights Reserved.

text-pattern

String pattern used for matching the message text (default = ... which matches
any string). A given message is issued to the screen only if its message string
matches the specified text-pattern string. For SDMs, the ID string is considered as
the message string for this purpose.
For more information, on string matching, see Native Specman String Matching
on page 99.

rec

Recursion indicator (default = TRUE):

If TRUE, the new setting will apply to all units in the unit subtree under the
given unit.
If FALSE, the new setting will apply to the given unit instance only, and will
not apply to other units in its unit subtree.

Description
This method belongs to the message_manager predefined type. It modifies messages that will/will not
be sent to the screen (and the main log file).
This methods have either of the following formats:

set_screen_messages() This method selects which messages from the unit and its subtree with
the specified tag will be sent to the screen (and main log file). The selection is done according to the
verbosity, modules, and text-pattern parameters.
set_screen_messages_off() This method disable the sending of messages with the specified tag
to the screen (and main log file).

Note This method only allows one tag setting to be modified. If a similar setting needs to be applied
to several tags with the same destination, several method calls should be performed accordingly.

Example
extend my_env {
post_generate() is also {
message_manager.set_screen_messages_off(me, NORMAL);
message_manager.set_screen_messages(me.the_agent.the_monitor, NORMAL,
HIGH);
};
};

See Also

set_transaction_messages | set_transaction_messages_off on page 969

Specman e Language Reference


1999-2015

968

Product Version 15.1


All Rights Reserved.

set_file_messages | set_file_messages_off on page 971

message_manager on page 959

19.4.1.2 set_transaction_messages | set_transaction_messages_off


Purpose
Modifies the selection of SDM messages issued by a given unit to the simulation database.

Category
Method

Syntax
set_transaction_messages (
root-unit: any_unit,
tag: message_tag,
verbosity: message_verbosity
[, modules: string [, text-pattern: string [, rec: bool]]]
)
set_transaction_messages_off (
root-unit: any_unit,
tag: message_tag
[, rec: bool]
)
Syntax Example
message_manager.set_transaction_messages(me.the_agent.the_monitor, NORMAL,
HIGH);
message_manager.set_transaction_messages_off(me, NORMAL);

Parameters
m

root-unit

Unit to which the new setting will be applied.

tag

Message tag to which the new setting applies. The new setting will only affect
messages of the specified tag.

Specman e Language Reference


1999-2015

969
.

Product Version 15.1


All Rights Reserved.

verbosity

Highest verbosity level for messages. A given message is issued to the transaction
only if its verbosity is equal to or lower than the specified verbosity.
Valid values are: NONE, LOW, MEDIUM, HIGH, and FULL.

modules

String pattern used for matching module names (wild cards permitted). A given
message is issued to the transaction only if it is defined in the specified module(s).
Default value is * which matches any module name.

text-pattern

String pattern used for matching the message text (default = ... which matches
any string). A given message is issued to the transaction only if its message string
matches the specified text-pattern string. For SDMs, the ID string is considered as
the message string for this purpose.
For more information, on string matching, see Native Specman String Matching
on page 99.

rec

Recursion indicator (default = TRUE):

If TRUE, the new setting will apply to all units in the unit subtree under the
given unit.
If FALSE, the new setting will apply to the given unit instance only, and will
not apply to other units in its unit subtree.

Description
This method belongs to the message_manager predefined type. It modifies messages that will/will not
be recorded in the simulation database. It affects only certain kinds of SDMs.
This method has either of the following formats:

set_transaction_messages() This method selects which SDM transaction messages from the unit
and its subtree with the specified tag will be sent to the simulation database. The selection is done
according to the verbosity, modules, and text-pattern parameters.
set_stransaction_messages_off() This method disables the sending of messages with the
specified tag to the simulation database.

Note This method only allows one tag setting to be modified. If a similar setting needs to be applied
to several tags with the same destination, several method calls should be performed accordingly.

Example
extend my_env {
post_generate() is also {
message_manager.set_transaction_messages_off(me, NORMAL);
Specman e Language Reference
1999-2015

970

Product Version 15.1


All Rights Reserved.

message_manager.set_transaction_messages(me.the_agent.the_monitor,
NORMAL, HIGH);
};
};

See Also

Methods for Modifying Message Selection on page 966

set_screen_messages | set_screen_messages_off on page 966

set_file_messages | set_file_messages_off on page 971

message_manager on page 959

19.4.1.3 set_file_messages | set_file_messages_off


Purpose
Modifies the selection of messages issued by a given unit to the specified log file(s).

Category
Method

Syntax
set_file_messages (
file-name: string,
root-unit: any_unit,
tag: message_tag,
verbosity: message_verbosity
[, modules: string [, text-pattern: string [, rec: bool]]]
)
set_file_messages_off (
file-name: string,
root-unit: any_unit,
tag: message_tag
[, rec: bool]
)
Syntax Example
message_manager.set_file_messages("my_file", me.the_agent.the_monitor,
NORMAL, HIGH);
Specman e Language Reference
1999-2015

971
.

Product Version 15.1


All Rights Reserved.

message_manager.set_file_messages_off("my_file", me, NORMAL);

Parameters
m

file-name

Log file to which the new setting will be applied.


Note This parameters is relevant only for set_file_messages() and
set_file_messages_off() methods.

root-unit

Unit to which the new setting will be applied.

tag

Message tag to which the new setting applies. The new setting will only affect
messages of the specified tag.

verbosity

Highest verbosity level for messages. A given message is issued to the specified
file only if its verbosity is equal to or lower than the specified verbosity.
Valid values are: NONE, LOW, MEDIUM, HIGH, and FULL.

modules

String pattern used for matching module names (wild cards permitted). A given
message is issued to the specified file only if it is defined in the specified
module(s). Default value is * which matches any module name.

text-pattern

String pattern used for matching the message text (default = ... which matches
any string). A given message is issued to the specified file only if its message
string matches the specified text-pattern string. For SDMs, the ID string is
considered as the message string for this purpose.
For more information, on string matching, see Native Specman String Matching
on page 99.

rec

Recursion indicator (default = TRUE):

If TRUE, the new setting will apply to all units in the unit subtree under the
given unit.
If FALSE, the new setting will apply to the given unit instance only, and will
not apply to other units in its unit subtree.

Description
This method belongs to the message_manager predefined type. It modifies messages that will/will not
be sent to log files.
This method has either of the following formats:

Specman e Language Reference


1999-2015

972

Product Version 15.1


All Rights Reserved.

set_file_messages() This method selects which messages from the unit and its subtree with the
specified tag will be sent to the specified log files. The selection is done according to the verbosity,
modules, and text-pattern parameters.
set_file_messages_off() This method disables the sending of messages with the specified tag to
the log files.

Note This method allows only one tag setting to be modified. If a similar setting needs to be applied
to several tags for the specified destinations, several method calls should be performed accordingly.

Example
extend my_env {
post_generate() is also {
message_manager.set_file_messages_off("my_file", me, NORMAL);
message_manager.set_file_messages("my_file", me.the_agent.the_monitor,
NORMAL, HIGH);
};
};

See Also

Methods for Modifying Message Selection on page 966

set_screen_messages | set_screen_messages_off on page 966

set_transaction_messages | set_transaction_messages_off on page 969

message_manager on page 959

19.4.2

Method for modifying message characteristics

The following methods modify message characteristics:

set_message_format() on page 974

set_message_style() on page 975

set_flush_frequency() on page 977

See Also

Methods for Modifying Message Settings (via message_manager) on page 966

Methods for Modifying Message Selection on page 966

Specman e Language Reference


1999-2015

973
.

Product Version 15.1


All Rights Reserved.

19.4.2.1 set_message_format()
Purpose
Modifies the format of messages that are issued by the specified unit or unit subtree with the specified
tag when sending them to the specified text destination(s).

Category
Method

Syntax
set_message_format(
root-unit: any_unit,
tag: message_tag,
file-names: list of string,
format: message_format
[, rec: bool]
)
Syntax Example
message_manager.set_message_format(me, NORMAL, {}, long);

Parameters
m

root-unit

Unit to which the new format setting will be applied.

tag

Message tag to which the new format setting applies. The new setting will only
affect messages of the specified tag.

file-names

List of file names to which the new format settings will be applied. An empty
string in the list denotes the screen. If the entire list is empty, the new settings will
be applied to all text destinations.

format

Format to be used for messages. Valid predefined values: none, short, and long.
You can also specify a user-defined value that was added by extending the
message_format type. For more information, see Method for User-Defined
Message Formatting on page 978.

Specman e Language Reference


1999-2015

974

Product Version 15.1


All Rights Reserved.

rec

Recursion indicator (default = TRUE):

If TRUE, the new format setting will apply to all units in the unit subtree under
the given unit.
If FALSE, the new format setting will apply to the given unit instance only,
and will not apply to other units in its unit subtree.

Description
This method belongs to the message_manager predefined type. It modifies the format of messages with
the specified tag when sending them to the specified text destination(s) by the specified unit or unit
subtree.

Example
unit my_env {
post_generate() is also {
message_manager.set_message_format(me, NORMAL, {}, long);
};
};

See Also

Method for modifying message characteristics on page 973

set_message_style() on page 975

set_flush_frequency() on page 977

message_manager on page 959

19.4.2.2 set_message_style()
Purpose
Specifies a color style for the message body-text.

Category
Method

Specman e Language Reference


1999-2015

975
.

Product Version 15.1


All Rights Reserved.

Syntax
set_message_style(
style: vt_style,
tag: message_tag,
[, verbosity: message_verbosity [, modules: string [, text-pattern: string]]]
)
Syntax Example
message_manager.set_message_style(PURPLE, MY_TAG, MEDIUM, "*", "monitoring
burst");

Parameters
style

Color name to be applied to the selected messages. For the list of color styles that can
be applied, see the description of the vt.text_style() method in Specman Deprecation
and Backwards Compatability.

tag

Message tag of the messages to which the new color setting will be applied.

verbosity

Highest verbosity level for application of the new color setting. The new color setting
will be applied to selected messages having the specified verbosity level or lower.
Default = FULL.Valid values are LOW, MEDIUM, HIGH, and FULL.

modules

Module name(s). Can be a string pattern with wild cards. The new color setting will be
applied only to selected messages residing in the specified module(s). Default value is
* which matches any module name.

text-pattern

String pattern used for matching the message text (default = ... which matches any
string). The new color setting will be applied only to selected messages whose text
contains a match to the specified string pattern. For SDMs, the ID string is considered
as the message string for this purpose.
For more information, on string matching, see Native Specman String Matching on
page 99.

Description
This method belongs to the message_manager predefined type. It modifies the text color of messages,
when they are sent to screen. This setting is done globally on the selected message actions, and not per
unit instance or subtree.

Specman e Language Reference


1999-2015

976

Product Version 15.1


All Rights Reserved.

Example
In the following example, the set_message_style() method colors in PURPLE all message text
containing the string monitoring burst in messages with the MEDIUM verbosity and the tag
MY_TAG:
post_generate() is also {
message_manager.set_message_style(PURPLE, MY_TAG, MEDIUM, "*",
"monitoring burst");
};

See Also

Method for modifying message characteristics on page 973

set_message_format() on page 974

set_flush_frequency() on page 977

message_manager on page 959

set message -style in Specman Command Reference

19.4.2.3 set_flush_frequency()
Purpose
Sets the flush frequency for the specified message file.

Category
Method

Syntax
set_flush_frequency(
file_name: string,
new_frequency: int)
Syntax Example
message_manager.set_flush_frequency("my_log_file.elog", 10);

Specman e Language Reference


1999-2015

977
.

Product Version 15.1


All Rights Reserved.

Parameters
file_name

Name of an existing message file. If no extension is given, the extension .elog is


appended automatically.

new_frequency New flush frequency. This value must be a positive number.

Description
This method looks for an existing message file by the given name, previously set with
message_manager.set_file_messages() or with a set message file=... command, and sets its flush
frequency to the specified value.
If a flush frequency is set to a message file, that file will be automatically flushed each time after the
given number of messages were issued to that file.
Typically, set_flush_frequency() should be called during prerun generation, just like other
message_manager methods that determine message settings.This functionality is useful when the user
needs to examine the content of a message file in the middle of a run. For example, the run may be
stopped on a break point, and the user may need to analyze messages issued up to that point.

Example
extend sys {
post_generate() is also {
message_manager.set_file_messages("my_file", me, MY_TAG, HIGH);
message_manager.set_flush_frequency("my_file", 10);
};
};

See Also

Method for modifying message characteristics on page 973

set_message_format() on page 974

set_message_style() on page 975

message_manager on page 959

set message -style in Specman Command Reference

19.5 Method for User-Defined Message Formatting


This section describes the following components:
Specman e Language Reference
1999-2015

978

Product Version 15.1


All Rights Reserved.

create_formatted_message() on page 979

19.5.1

create_formatted_message()

Purpose
Defines user-defined message formatting.

Category
Hook (callback) method

Syntax
any_unit.create_formatted_message(
message: message_action,
buffer: list of string
)
Syntax Example
extend any_unit {
create_formatted_message(message: message_action, buffer: list of string)
is also {
buffer.add0(append("sys.time is %s", message.get_time()));
};
};

Parameters
message

Message being issued.

buffer

Buffer for the formatted message.

Description
The create_formatted_message() method is a hook (callback) method used for implementing
user-defined formatting on message output. This method only gets called when the message is being sent
to the screen and/or to file destination(s) it can be called more than once for the same message and it
creates the actual message text that will be sent.

Specman e Language Reference


1999-2015

979
.

Product Version 15.1


All Rights Reserved.

At the start of this method, buffer contains the base text of the message before formatting. The default
implementation of this method uses the default formatting of the three formats (short, long, and none),
according to the message format settings.
create_formatted_message() has a parameter of the predefined message_action type, and you can
extend create_formatted_message() to use the message_action methods listed in Table 19-1 on page
962.
To implement custom formats on output messages, you can extend create_formatted_message() to
implement the message_format that is returned by the get_format() method of message_action. When
doing so, you must write the updated message text into the buffer.
The various data provided by the message parameter can be used both to apply conditions on the
resulting text and to append that data itself to the message text.
Notes

This methods should only be used for the actual message formatting. It should not be used for other
purposes (e.g., modifying fields, creating its own messages, or creating additional printings).
While this method can be extended by the user, it should not be called directly from user's code. It
is called automatically by Specman.
If the user extension of create_formatted_message() uses is also, the content of buffer at the
beginning of the user's extension contains the default formatting. If it uses is only, the default
formatting is not performed, and the content of buffer is just the base text of the message.
The create_formatted_message() method is only used for text destinations. It is not relevant for the
transactions database destination.
If you set a breakpoint on create_formatted_message(), the debugger might not stop on it for every
message action, because whether the method actually gets called depends on the message settings.

Example
To override the default format for MY_TAG messages that are handled by the unit env_u and its
subtree, do the following:
1.

Define a new message format. For example:


extend message_format: [MY_FORMAT};

Now the list of valid formats is as follows:


[short, long, none, MY_FORMAT]

2.

Set the message format of env_u to MY_FORMAT:


unit env_u {
post_generate() is also {

Specman e Language Reference


1999-2015

980

Product Version 15.1


All Rights Reserved.

message_manager.set_message_format(me, MY_TAG, {},MY_FORMAT);


};
};

3.

Extend the create_formatted_method() to create the desired message string when the message has
the format MY_FORMAT:
extend any_unit {
create_formatted_message(message: message_action, \\
buffer: list of string) is first {
if message.get_format() == MY_FORMAT {
var src_module: rf_module = \\
message.get_source_method_layer().get_module();
var src: string = append("at line ", \\
message.get_source_line_num(), \\
" in @", \\
src_module.get_name());
buffer.add0(src);
buffer.add0(append("sys.time is %s\n", \\
message.get_time()));
return;
};
};
};

This example calls the get_format() method to return the format of the current message. If the
message has the format MY_FORMAT, it calls get_time() to return the current value of sys.time. It
updates the content of buffer, which contains the resulting list of strings to be output. Each string
added to buffer is automatically followed by a newline, except for the last. This example includes a
newline (\n) as the last string in the list to add a blank line after the message.
When you run the test, messages handled by MY_TAG are displayed in the new format; other messages
are displayed in the standard format. For example, in the following test run, the first two messages have
the standard format, and the second two have the new format:
[375] ENV MON1 : In address phase. Sending to addr: 19
[375] ENV MON2 : In address phase. Sending to addr: 4
sys.time is 376
at line 42 in @my_simple
(ended - monitoring frame) frame-@199
sys.time is 376
at line 42 in @my_simple
(ended - monitoring frame) frame-@200

Specman e Language Reference


1999-2015

981
.

Product Version 15.1


All Rights Reserved.

See Also

Actions for Defining Structured Debug Messages (SDMs) on page 941

Actions for Defining Regular Messages on page 955

Predefined Types Related To Messaging on page 958

Methods for Modifying Message Settings (via message_manager) on page 966

recording_config API on page 982

19.6 recording_config API


The recording configuration API lets you control the attributes and state variables that are reported by
messages.
The recording_config struct encapsulates transaction recording configuration for a unit or for numerous
units at once. The configuration is determined procedurally through API calls. The initialization of
config objects and their assignment to units is typically performed before simulation starts and remains
constant throughout the run, but nothing in any of the API methods precludes changing the
configuration dynamically.
The following sections describe this API:

recording_config Methods on page 982

any_unit API extension on page 1001

any_stuct API Extension on page 1004

19.6.1

recording_config Methods

The following are methods of the recording_config API:

register_all_field_attributes() on page 983

register_callback_attribute() on page 984

register_callback_attributes() on page 985

register_callback_state_var() on page 986

register_fiber_mapping() on page 987

register_field_attribute() on page 989

register_field_attributes() on page 990

register_field_state_var() on page 991

register_method_attribute() on page 992

register_method_state_var() on page 993

Specman e Language Reference


1999-2015

982

Product Version 15.1


All Rights Reserved.

set_attribute_format() on page 995

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

set_text_state_var() on page 999

Type tr_sampling_point_t on page 1000

See Also

any_unit API extension on page 1001

any_stuct API Extension on page 1004

Actions for Defining Structured Debug Messages (SDMs) on page 941

Actions for Defining Regular Messages on page 955

Predefined Types Related To Messaging on page 958

Methods for Modifying Message Settings (via message_manager) on page 966

Method for User-Defined Message Formatting on page 978

19.6.1.1 register_all_field_attributes()
Syntax
register_all_field_attributes(type-name: string)

Parameters
type-name

Any struct type name, including when subtypes and template instances

Description
Defines all user-defined public fields to be recorded as transactions attributes for data-items of the
specified type.
Note Different sets of fields may be recorded for instances of different when/like subtypes of
type-name.

Specman e Language Reference


1999-2015

983
.

Product Version 15.1


All Rights Reserved.

See Also

register_callback_attribute() on page 984

register_callback_attributes() on page 985

register_callback_state_var() on page 986

register_fiber_mapping() on page 987

register_field_attribute() on page 989

register_field_attributes() on page 990

register_field_state_var() on page 991

register_method_attribute() on page 992

register_method_state_var() on page 993

set_attribute_format() on page 995

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

set_text_state_var() on page 999

Type tr_sampling_point_t on page 1000

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.2 register_callback_attribute()
Syntax
register_callback_attribute(type-name: string, attr-name: string)

Parameters
type-name

Any struct type name, including when subtypes and template instances

attr-name

An attributes name to be associated with the struct

Specman e Language Reference


1999-2015

984

Product Version 15.1


All Rights Reserved.

Description
Defines an attribute for transactions of the specified type, the value of which is determined dynamically
by the hook method tr_get_attribute_value(). Whenever a transaction of the given type needs to be
sampled, the hook method is called on the data-item type. If this call returns an empty string, the same
method is called on the scope unit. The attribute name is written along with the returned value from
either of the calls.
Notes

The callback function must be implemented for every type in which such a message is called. For
example, assume it is implemented in the frame_monitor. If an SDM with frame is called in a
scoreboard, it would need to be implemented in the scoreboard as well.
When the hook method is implemented on the data item type, Cadences recommends using method
attributes instead (see register_method_attribute() on page 992).

Example
In this example, the attribute destination is calculated by the monitor when the message is recorded.
extend frame_monitor {
connect_pointers() is also {
var tr_cfg:recording_config = new;
tr_cfg.register_field_attributes("frame",{"addr";} );
tr_cfg.register_callback_attribute("frame","destination");
assign_recording_config(tr_cfg);
};
tr_get_attribute_value(inst:any_struct,name:string):string is also {
if inst is a frame (f) and name == "destination" then {
result = append(me.base_addr + f.addr);
};
};
};

19.6.1.3 register_callback_attributes()
Syntax
register_callback_attributes(type-name: string, attr-names: list of string)

Parameters

Specman e Language Reference


1999-2015

985
.

Product Version 15.1


All Rights Reserved.

type-name

Any struct type name, including when subtypes and template instances

attr-name

A list of attributes names to be associated with the struct

Description
Defines a set of callback attributes for transactions of the specified type. Calling this method is
equivalent to calling register_field_attribute() for each of the given field names.
Note When the hook method is implemented on the data item type, Cadences recommends using
method attributes instead (see register_method_attribute() on page 992).

19.6.1.4 register_callback_state_var()
Syntax
register_callback_state_var(unit-name: string, var-name: string)

Parameters
unit-name

A name of a unit type (including when subtypes and template instances).

var-name

A legal identifier that will figure as the attribute name in the destination.

Description
Defines a state variable, the value of which is determined dynamically by the unit hook method
tr_get_state_var_value() on page 1004. The value is sampled by calling the hook method upon the
execution of msg_changed() when the scope unit is of the specified type. Both name and the returned
value are written to the message destination.
Notes

Text destinations (screen and log files) require explicit additional setting to show the attribute (see
set_text_state_var() on page 999).
Cadence recommends using method state variables instead (seeregister_method_state_var() on
page 993).

See Also

register_all_field_attributes() on page 983

Specman e Language Reference


1999-2015

986

Product Version 15.1


All Rights Reserved.

register_fiber_mapping() on page 987

register_field_attribute() on page 989

register_field_attributes() on page 990

register_field_state_var() on page 991

register_method_attribute() on page 992

register_method_state_var() on page 993

set_attribute_format() on page 995

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

set_text_state_var() on page 999

Type tr_sampling_point_t on page 1000

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.5 register_fiber_mapping()
Syntax
register_fiber_mapping(id-str: string, fiber-name: string [, overlap: bool])

Parameters
id-str

A string value that is used as id argument in structured messages.

fiber-name

The intended name for the waveform fiber.

Specman e Language Reference


1999-2015

987
.

Product Version 15.1


All Rights Reserved.

overlap

A boolean value that controls whether transactions are to be shown with time overlaps
on the given fiber. The default value for overlap is TRUE.
If you call register_fiber_mapping() passing only two parameters (id-string and
fiber-name), overlap automatically takes the default value; therefore, a transaction
opened by msg_started() is not closed by default without a corresponding msg_ended()
being emitted. This is very useful when recording information of transactions occurring
in parallel, such as pipelined protocols.
When the value is set to FALSE, transaction overlaps are not created, and the open
transactions automatically end when the next msg_started() is called for the same fiber
even if no msg_ended() has been emitted prior to that.

Description
Defines a mapping between messages with the specified id as argument and the waveform fiber name in
which the resulting transactions should figure.
Notes

If no mapping for a given id is registered the id string itself is used as the waveform fiber name.

If multiple mapping rules are registered for the same id the one registered latest applies.

It is legal to map multiple id values to the same fiber name.

See Also

register_all_field_attributes() on page 983

register_callback_attribute() on page 984

register_callback_attributes() on page 985

register_callback_state_var() on page 986

register_field_attribute() on page 989

register_field_attributes() on page 990

register_field_state_var() on page 991

register_method_attribute() on page 992

register_method_state_var() on page 993

set_attribute_format() on page 995

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

Specman e Language Reference


1999-2015

988

Product Version 15.1


All Rights Reserved.

set_text_state_var() on page 999

Type tr_sampling_point_t on page 1000

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.6 register_field_attribute()
Syntax
register_field_attribute(type-name: string, field-name: string)

Parameters
type-name

Any struct type name, including when subtypes and template instances

field-name

A name of a field declared for the struct

Description
Defines the specified data item field to be recorded as a transaction attribute. The field is sampled upon
the execution of structured messages of certain kinds when given data-items of the specified type as
parameters. Both name and value of the attribute are written to the message destination. By default, this
happens on both msg_started() and msg_ended(), but other sampling points may be designated for a
given attribute using the API call set_text_attribute().
Note Text destinations (screen and log files) require explicit additional setting to show the attribute
(see set_attribute_sampling() on page 996).

Example
This example specifies that the field addr of the frame should be recorded, in all messages issued by the
xbus_monitor.
extend xbus_monitor {
connect_pointers() is also {
var tr_cfg : recording_config = new;
tr_cfg.register_field_attribute("frame", "addr");
assign_recording_config(tr_cfg);
};
};

Specman e Language Reference


1999-2015

989
.

Product Version 15.1


All Rights Reserved.

See Also

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.7 register_field_attributes()
Syntax
register_field_attributes(type-name: string, field-names: list of string)

Parameters
type-name

Any struct type name, including when subtypes and template instances

field-names

A list of field names declared for the struct

Description
Defines a set of field attributes for transactions of the specified type. Calling this method is equivalent to
calling register_field_attribute() for each of the given field names.

Example
This example specifies that the fields addr and data of the frame should be recorded, in all messages
issued by the xbus_monitor.
extend xbus_monitor {
connect_pointers() is also {
var tr_cfg : recording_config = new;
tr_cfg.register_field_attributes("frame", {"addr"; "data"});
assign_recording_config(tr_cfg);
};
};

See Also

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

Specman e Language Reference


1999-2015

990

Product Version 15.1


All Rights Reserved.

19.6.1.8 register_field_state_var()
Syntax
register_field_state_var(unit-name: string, field-name: string)

Parameters
unit-name

A name of a unit type (including when subtypes and template instances).

field-name

A name of a field declared for the struct.

Description
Defines the specified field to be recorded as a state variable. The field is sampled on the execution of
msg_changed() when the scope unit is of the specified type. Both name and value of the state variable
are written to the message destination.
Note Text destinations (screen and log files) require explicit additional setting to show the attribute
(see set_text_state_var() on page 999).

See Also

register_all_field_attributes() on page 983

register_callback_attribute() on page 984

register_callback_attributes() on page 985

register_callback_state_var() on page 986

register_fiber_mapping() on page 987

register_method_attribute() on page 992

register_method_state_var() on page 993

set_attribute_format() on page 995

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

set_text_state_var() on page 999

Type tr_sampling_point_t on page 1000

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

Specman e Language Reference


1999-2015

991
.

Product Version 15.1


All Rights Reserved.

19.6.1.9 register_method_attribute()
Syntax
register_method_attribute(type-name: string, method-name: string)

Parameters
type-name

Any struct type name, including when subtypes and template instances

method-name

Name of an existing method of the struct type

Description
Defines an attribute for transactions of the specified type, the value of which is determined dynamically
by calling the specified hook method of the data item struct type. Whenever a transaction of the given
type needs to be sampled, the hook method is called on the data item type. The attribute name is written
along with the returned value.
A struct by the specified name must exist and must have a method by the specified name. In addition, the
method must not be a TCM, must have a return type, and must either have no parameters, or have
exactly one parameter of type any_unit, which is not passed by reference; otherwise, an error will result.
At run time:

If the method has no parameters, it is just called on the data item.


If the method has one unit parameter, it is called on the data item and the scope unit is passed as the
parameter.

Example
In this example, two method attributes address and direction are registered for the frame, each one
implemented by a separate hook method. The hook method for address gets the scope unit as a
parameter. The hook method for direction does not use a scope unit, and so it has no parameters.
extend frame_monitor {
connect_pointers() is also {
var tr_cfg:recording_config = new;
tr_cfg.register_method_attribute("frame","address");
tr_cfg.register_method_attribute("frame","direction");
assign_recording_config(tr_cfg);
};
};

Specman e Language Reference


1999-2015

992

Product Version 15.1


All Rights Reserved.

This can be improved by registering the address and direction attributes with
register_method_attribute() instead of register_callback_attribute(), and by adding the following
two hook methods:
extend frame {
address(scope: any_unit): uint is {
if scope is a monitor (m) {
result = m.base_addr + header.addr;
};
};
direction(): direction_t is {
result = header.dir;
};
};

See Also

register_all_field_attributes() on page 983

register_callback_attribute() on page 984

register_callback_attributes() on page 985

register_callback_state_var() on page 986

register_fiber_mapping() on page 987

register_method_state_var() on page 993

set_attribute_format() on page 995

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

set_text_state_var() on page 999

Type tr_sampling_point_t on page 1000

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.10 register_method_state_var()
Syntax
register_method_state_var(unit-name: string, method-name: string)

Specman e Language Reference


1999-2015

993
.

Product Version 15.1


All Rights Reserved.

Parameters
unit-name

Name of a unit type (including when subtypes and template instances).

method-name

Name of an existing method of the unit type.

Description
Defines a state variable, the value of which is determined dynamically by calling the specified hook
method of the unit type. The value is sampled by calling the hook method upon the execution of
msg_changed() when the scope unit is of the specified type. Both name and the returned value are
written to the message destination.
A unit type by the specified name must exist and must have a method by the specified name. The method
must not be a TCM, must have a return type and must have no parameters; otherwise, an error will
result.
At run time, the method is called on the scope unit instance.
The return value is automatically converted to a string (applying the format specified by
set_attribute_format(), if any) before being assigned to the attribute being sampled.

See Also

register_all_field_attributes() on page 983

register_callback_attribute() on page 984

register_callback_attributes() on page 985

register_callback_state_var() on page 986

register_fiber_mapping() on page 987

register_method_attribute() on page 992

set_attribute_format() on page 995

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

set_text_state_var() on page 999

Type tr_sampling_point_t on page 1000

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

Specman e Language Reference


1999-2015

994

Product Version 15.1


All Rights Reserved.

19.6.1.11 set_attribute_format()
Syntax
set_attribute_format(type-name: string, attr-name: string, format: string)

Parameters
type-name

Any struct type name, including when subtypes and template instances.

attr-name

Registered attribute name for the given struct type.

string

Format string to be used.

Description
Determines that an already registered attribute or state variable will be converted to a string using the
specified format string. If there is no attribute by that name currently registered within this
recording_config object, an error is issued. The format string must be a legal format string with exactly
one "%..." parameter that is applicable to the attribute's type. If the format string does not meet these
requirements, and error is issued. (For more information, see Format String on page 1528.)
Note The setting done with set_attribute_format() affects all message destinations. For text
destinations, if the attribute is also set to be a text attribute (with set_text_attribute() ), it will be printed
using the specified format string. For transactions destination, the attribute will be displayed as a
transaction attribute using the specified format string. In Smartlog, the attribute will also be shown using
the specified format string (for more information, see Debugging with Incisive Debug Analyzer).

Example
In this example, the "addr" attribute will be printed in hexadecimal format, and the "data" attribute will
be printed in decimal format.
extend xbus_monitor {
connect_pointers() is also {
var tr_cfg : recording_config = new;
tr_cfg.register_field_attributes("frame", {"addr"; "data"});
tr_cfg.set_attribute_format("frame", "addr", "%#x");
tr_cfg.set_attribute_format("frame", "data", "%d");
assign_recording_config(tr_cfg);
};
};

Specman e Language Reference


1999-2015

995
.

Product Version 15.1


All Rights Reserved.

See Also

register_all_field_attributes() on page 983

register_callback_attribute() on page 984

register_callback_attributes() on page 985

register_callback_state_var() on page 986

register_fiber_mapping() on page 987

register_method_attribute() on page 992

register_method_state_var() on page 993

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

set_text_state_var() on page 999

Type tr_sampling_point_t on page 1000

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.12 set_attribute_sampling()
Syntax
set_attribute_sampling(type-name: string, attr-name: string, points: list of tr_sampling_point_t)

Parameters
type-name

Any struct type name, including when subtypes and template instances.

attr-name

A registered attribute name for the given struct type.

points

A list of zero or more values representing structured message sampling points


(See Type tr_sampling_point_t on page 1000).

Description
Determines that an already registered attribute is to be sampled and recorded at the specified sampling
points. If there is no attribute by that name currently registered within this recording_config object, an
error is issued. The sampling points correspond to different roles of the data item within structured
messages. The setting for the specified attribute overrides the previous setting.
Specman e Language Reference
1999-2015

996

Product Version 15.1


All Rights Reserved.

The possible sampling points are defined by the tr_sampling_point_t enumerated type. The values of
this enumerated type represent possible points of sampling for data item attributes, as follows:

STARTED the data-item argument of msg_started()

ENDED the data-item argument of msg_ended()

TRANSFORMED The from-item (first) or to-item (second) argument of msg_transformed()

CHANGED State variables of the scope unit.

INFO The data-item arguments of msg_info()

The default setting for all attributes is the element list {STARTED; ENDED}.

See Also

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.13 set_label_attribute()
Syntax
set_label_attribute(type-name: string, attr-name: string)

Parameters
type-name

Any struct type name, including when subtypes and template instances.

attr-name

A registered attribute name for the given struct type.

Description
Sets an already registered attribute as the transaction label for transaction of the given type. If there is no
attribute by that name currently registered within this recording_config object an error is issued.
Notes

This setting only affects the simulation database; it does not affect other destinations.
The attribute is recorded only as a transaction label and not as a transaction attribute. Thus, the
attribute name is not captured in the simulation database.
If no label attributes applies to a given data item the default label is used, which is the instance name
in the form type-@inst-id.

Specman e Language Reference


1999-2015

997
.

Product Version 15.1


All Rights Reserved.

When multiple label attributes apply to the same data item the last registered attribute is used.
The sampling point for a label attribute must be set to STARTED, otherwise, it will not be treated
as a label, even if set_label_attribute() has been called on it. The attribute will appear as a regular
attribute rather than a label attribute.

See Also

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.14 set_text_attribute()
Syntax
set_text_attribute(type-name: string, attr-name: string)

Parameters
type-name

Any struct type name, including when subtypes and template instances.

attr-name

A registered attribute name for the given struct type.

Description
Determines that an already registered attribute is to be written also to text destinations (screen and log
files). If there is no attribute by that name currently registered within this recording_config object an
error is issued.
Note

This setting does not affect destinations other than screen and log files.

Example
This example specifies that the fields addr and data of the frame should be recorded, in all messages
issued by the xbus_monitor, and also written to text destinations.
extend xbus_monitor {
connect_pointers() is also {
var tr_cfg : recording_config = new;
tr_cfg.register_field_attributes("frame", {"addr"; "data"});
tr_cfg.set_text_attribute("frame","addr");
tr_cfg.set_text_attribute("frame","data");
assign_recording_config(tr_cfg);
Specman e Language Reference
1999-2015

998

Product Version 15.1


All Rights Reserved.

};
};

For instance, the following message:


msg_ended(HIGH,"monitoring transfer",cur_trans);

may produce the following output on screen or in the log file:


[63400] ENV_0 M0 MON: (started - monitoring transfer)
my_evc_monitor_transfer-@338 {addr=0x877bc445; data=0xec538edc}

See Also

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.15 set_text_state_var()
Syntax
set_text_state_var(unit-name: string, var-name: string)

Parameters
unit-name

Any struct type name, including when subtypes and template instances.

var-name

A registered attribute name for the given struct type.

Description
Determines that an already registered state variable is also written to text destinations (screen and log
files). If there is no state variable by that name currently registered within this recording_config object,
an error is issued.
Note

This setting does not affect destinations other than screen and log files.

See Also

register_all_field_attributes() on page 983

register_callback_attribute() on page 984

register_callback_attributes() on page 985

Specman e Language Reference


1999-2015

999
.

Product Version 15.1


All Rights Reserved.

register_callback_state_var() on page 986

register_fiber_mapping() on page 987

register_field_attribute() on page 989

register_field_attributes() on page 990

register_field_state_var() on page 991

Type tr_sampling_point_t on page 1000

recording_config Methods on page 982

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.1.16 Type tr_sampling_point_t


Purpose
Used to define the smapling points for data item attributes.

Category
Type

Description
The values selected in this enumerated type are used to determine points of sampling for data item
attributes that are set using set_attribute_sampling() on page 996.
type tr_sampling_point_t: [STARTED,
ENDED,
TRANSFORMED,
CHANGED,
INFO];

Possible points are described below.

STARTED The data-item argument of msg_started()

ENDED The data-item argument of msg_ended()

TRANSFORMED The from-item (first) or to-item (second) argument of msg_transformed()

CHANGED State variables of the scope unit.

INFO The data-item arguments of msg_info()

Specman e Language Reference


1999-2015

1000

Product Version 15.1


All Rights Reserved.

See Also

register_all_field_attributes() on page 983

register_callback_attribute() on page 984

register_callback_attributes() on page 985

register_callback_state_var() on page 986

register_fiber_mapping() on page 987

register_field_attribute() on page 989

register_field_attributes() on page 990

register_field_state_var() on page 991

set_attribute_sampling() on page 996

set_label_attribute() on page 997

set_text_attribute() on page 998

set_text_state_var() on page 999

recording_config Methods on page 982

19.6.2

any_unit API extension

The following sections describe the Unit Register Recording methods belonging to any_unit:

assign_recording_config() on page 1001

get_recording_config() on page 1002

tr_get_attribute_value() on page 1002

tr_get_state_var_value() on page 1004

See Also

recording_config API on page 982

recording_config Methods on page 982

any_stuct API Extension on page 1004

19.6.2.1 assign_recording_config()
Syntax
assign_recording_config(rec: recording_config)

Specman e Language Reference


1999-2015

1001
.

Product Version 15.1


All Rights Reserved.

Description
Assigns the given recording_config object to this unit instance. Note that this affects the configuration
of all descendant units that have not been assigned a recording_config object explicitly, or associated
with one through a closer parent.

See Also

any_unit API extension on page 1001

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.2.2 get_recording_config()
Syntax
get_recording_config(): recording_config

Description
Returns the recording_config object that is associated with this unit instance. A unit is associated with
a recording_config object either by explicit assignment using assign_recording_config() on page 1001
or otherwise inherits the association from its parent unit (recursively). Unit sys (and units with no parent
unit in general) is associated by default with an empty recording_config object.

See Also

any_unit API extension on page 1001

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.2.3 tr_get_attribute_value()
Syntax
tr_get_attribute_value(inst: any_struct, attr-name: string): string

Parameters
inst

A reference to the data item instance that is being considered.

attr-name

The name of the registered attributes.

Specman e Language Reference


1999-2015

1002

Product Version 15.1


All Rights Reserved.

Description
A callback method that returns the value of an attribute for the given instance. It is invoked on data-item
instances for which the attribute was registered at the appropriate sampling points. The value retuned by
it is written to the message destination.
Notes

This method may be implemented by the user but should not be called explicitly. By default, it returns
"" (an empty string).
Specman calls this method only when a previous call to a method by the same name on the data-item
instance returns an empty string, in particular, if it is not defined by the user. (See
tr_get_attribute_value() any_struct API extension.)
tr_get_attribute_value() is strongly connected to register_callback_attribute()

Example
In this example, the attribute destination is calculated by the monitor when the message is recorded.
extend frame_monitor {
connect_pointers() is also {
var tr_cfg : recording_config = new;
tr_cfg.register_field_attributes("frame",{"addr";} );
tr_cfg.register_callback_attribute("frame", "destination"); \\
assign_recording_config(tr_cfg);
};
tr_get_attribute_value(inst: any_struct, name: string): string is also {
if inst is a frame (f) and name == "destination" then {
result = append(me.base_addr + f.addr);
};
};
};

See Also

any_unit API extension on page 1001

Specman e Language Reference


1999-2015

1003
.

Product Version 15.1


All Rights Reserved.

19.6.2.4 tr_get_state_var_value()
Syntax
tr_get_state_var_value(attr-name: string): string

Parameters
attr-name

The name of the registered attributes.

Description
A callback method that returns the value of a registered state variable for this unit instance. It is invoked
on scope units for which the state variable was registered upon execution of msg_changed(). The value
returned by it is written to the message destination.
Notes

This method may be implemented by the user but should not be called explicitly. By default it returns
"" (an empty string).
Cadence recommends using method state variables instead (seeregister_method_state_var() on
page 993).

See Also

any_unit API extension on page 1001

Modifying Transaction Logging Attributes in Creating e Testbenches

19.6.3

any_stuct API Extension

The following sections describe the Recording Configuration methods belonging to any_struct:

tr_get_attribute_value() on page 1005

See Also

recording_config API on page 982

recording_config Methods on page 982

any_unit API extension on page 1001

Specman e Language Reference


1999-2015

1004

Product Version 15.1


All Rights Reserved.

19.6.3.1 tr_get_attribute_value()
Syntax
tr_get_attribute_value(scope: any_unit, attr-name: string): string

Parameters
scope

A reference to the unit in the scope where the attribute should be evaluated.

attr-name

The name of the registered attributes.

Description
A callback method that returns the value of an attribute for this data-item instance in the given scope
unit. It is invoked on data-item instances for which the attribute was registered at the appropriate
sampling points by calling register_callback_attribute(). The returned value is written to the message
destination.
Notes

This method may be implemented by the user, but should not be called explicitly. By default it returns
"" (an empty string).
tr_get_attribute_value() is strongly connected to register_callback_attribute().
When the hook method is implemented on the data item type, Cadences recommends using method
attributes instead (see register_method_attribute() on page 992).

Example
In this example, the tr_get_attribute_value() callback method is extended to calculate and return the
frame address when the message is emitted by the monitor:
extend frame {
tr_get_attribute_value(scope: any_unit, attr-name: string): string
is also {
if scope is a monitor (m) {
if attr-name == "address" then {
result = append(m.base_addr + header.addr);
};
if attr-name == "direction" then {
result = append(header.dir);
};
};

Specman e Language Reference


1999-2015

1005
.

Product Version 15.1


All Rights Reserved.

};
};

See Also

any_stuct API Extension on page 1004

register_callback_attribute() on page 984

Modifying Transaction Logging Attributes in Creating e Testbenches

19.7 Messaging Interfaces Under Deprecation


Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.
This section contains the following topics:

How Regular Message Actions are Handled on page 1006

Messaging Procedural Interface Methods on page 1007

Methods for Extending accept_message() and format_message() on page 1021

19.7.1

How Regular Message Actions are Handled

Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported. For information on the current non-logger based messaging
system, see message() and messagef() on page 956.
Where the old API (that supports loggers) is being used, when a message action is executed, the
following happens:

If there are no handling loggers for the action, the action is skipped.
If there are handling loggers for the action, the action creates a message (consisting of a list of string
plus related information) and sends it to all of the handling loggers. Those loggers then format the
message and send it to the relevant destinations.

Specman e Language Reference


1999-2015

1006

Product Version 15.1


All Rights Reserved.

19.7.2

Messaging Procedural Interface Methods

Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported. For information on the current non-logger based messaging
system, see Predefined Types Related To Messaging on page 958 and Methods for Modifying Message
Settings (via message_manager) on page 966.
This section describes the following methods:

allocate_tags() on page 1007

get_tags() on page 1008

ignore_tags() on page 1009

set_actions() on page 1010

set_file() on page 1012

set_format() on page 1013

set_screen() on page 1014

set_style() on page 1015

set_trans() on page 1017

show_actions() on page 1018

show_message() on page 1019

show_units() on page 1020

19.7.2.1 allocate_tags()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Assigns a new tag to the logger.

Category
Method

Specman e Language Reference


1999-2015

1007
.

Product Version 15.1


All Rights Reserved.

Syntax
allocate_tags(new-tag: list of message_tag)

Parameters
new-tag

List of message tags

Description
Adds a tag to the list of tags that a logger handles.

Example
The following example first defines two tags, MY_TAG and NEW_TAG. The logger, my_logger, is
defined in the env_u unit. It uses soft constraints to add MY_TAG to the list of tags handled by
my_logger, and it uses allocate_tags() to add NEW_TAG to the list of tags:
extend message_tag: [MY_TAG, NEW_TAG];
.
.
.
unit env_u {
my_logger: message_logger is instance;
keep soft my_logger.tags == {MY_TAG};
post_generate() is also {
my_logger.allocate_tags({NEW_TAG});
};
};

When you run a test that uses this logger, my_logger handles messages with the following tags:

MY_TAGAllocated by a soft constraint

NEW_TAGAdded by allocate_tags()

19.7.2.2 get_tags()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Specman e Language Reference


1999-2015

1008

Product Version 15.1


All Rights Reserved.

Purpose
Returns a list of the tags currently recognized by the logger

Category
Method

Syntax
get_tags(): list of message_tag

Description
Returns a list of tags recognized by the logger.

19.7.2.3 ignore_tags()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Forces the logger to ignore the specified tags.

Category
Method

Syntax
ignore_tags(tags:list of message_tag)

Parameters
tags

List of message tags

Description
Removes the specified tag or tags from the list of tags that are handled by the message logger.
Specman e Language Reference
1999-2015

1009
.

Product Version 15.1


All Rights Reserved.

Example
The following example first defines two tags, MY_TAG and NEW_TAG. The logger, my_logger, is
instantiated in the env_u unit. It uses soft constraints to add NORMAL and MY_TAG to the list of tags
handled by my_logger. Later, it then uses allocate_tags() to add NEW_TAG to the list of tags and
ignore_tags() to remove NORMAL and MY_TAG from the list:
extend message_tag: [MY_TAG, NEW_TAG];
.
.
.
unit env_u {
my_logger: message_logger is instance;
keep soft my_logger.tags == {NORMAL; MY_TAG};
.
.
.
post_generate() is also {
my_logger.allocate_tags({NEW_TAG});
my_logger.ignore_tags({NORMAL; MY_TAG});
};
};

When you run a test that uses this logger, my_logger handles only those messages that have the
NEW_TAG tag.

See Also

set message -ignore_tags in Specman Command Reference

19.7.2.4 set_actions()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Adds, replaces, or removes the specified logger actions.

Category
Method

Specman e Language Reference


1999-2015

1010

Product Version 15.1


All Rights Reserved.

Syntax
set_actions(verbosity: message_verbosity, tags: list of message_tag , module: string , text: string ,
op: operation)

Parameters
verbosity

Specifies the verbosity level that for message actions handled by this handler. Valid
values are LOW, MEDIUM, HIGH, and FULL.

Optional Parameters
tags

Specifies the tag, or tags, to be added, replaced, or removed. The default is NORMAL.

modules

Specifies a string pattern to match the names of the modules containing the selected
messages. The default is * to match all modules.

text

Specifies a string pattern. Any messages that match the string pattern are added, replaced,
or removed from the message output. The default is ... to match any text (for more
information, see Native Specman String Matching on page 99.

op

Specifies the operation you want to perform on the messages. Valid operators are add,
replace, or remove. The default is replace.

Description
Performs one of the following operations:

Adds the specified messages to those already handled by the logger

Replaces the specified messages handled by the logger

Removes the specified messages from the logger

Example
Suppose you have a message defined in a module, t1.e, as follows:
extend MAIN burst_seq {
!s1: SIMPLE burst_seq;
!s2: MOSTLY_MGMT burst_seq;
body()@driver.clock is only {
.
.
.
Specman e Language Reference
1999-2015

1011
.

Product Version 15.1


All Rights Reserved.

msg_info(NEW_TAG, LOW,"end of test ", s2);


};
};

You could use the set_actions() method to remove that message from the message output, as follows:
unit env_u {
my_logger: message_logger is instance;
keep soft my_logger.tags == {MY_TAG; NEW_TAG};
.
.
.
post_generate() is also {
my_logger.set_actions(HIGH, {NEW_TAG} , "my_t1", "...", remove);
};
};

See Also

set message in Specman Command Reference

19.7.2.5 set_file()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Enables or disables writing messages to the specified log file.

Category
Method

Syntax
set_file(fname: string, to: message_on_off)

Parameters
fname

Specifies the name of the file. The default file extension is .elog.

Specman e Language Reference


1999-2015

1012

Product Version 15.1


All Rights Reserved.

to

Specifies on to enable or off to disable writing messages to the log file.

Description
Adds the specified file to the logger, or removes the file from the logger destinations.
Each logger can write to any number of files. Users often want to log information into separate files (for
example, one file for each e UVC type or e UVC instance, one file altogether, and so on).

Example
The following example extends the post_generate() method to add a file called my_log.elog to the
logger destinations:
post-generate() is also {
my_logger.set_file("my_log", on);
};

See Also

set message -file in Specman Command Reference

19.7.2.6 set_format()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Defines the message format.

Category
Method

Syntax
set_format(format: message_format)

Specman e Language Reference


1999-2015

1013
.

Product Version 15.1


All Rights Reserved.

Parameters
format

Specifies a legal value for the predefined type message_format.


Initially, message_format is defined as:
type message_format: [short, long, none];

Loggers start out with the short format.


You can extend message_format. You can also format the output programmatically by
extending the logger.format_message() method. For more information, see
Controlling the Format of Messages in Creating e Testbenches.

Description
Specifies the message format that you want this logger to use.

Example
The following example sets the message format to NONE; only the message text is output.
post_generate() is also {
my_logger.set_format(none);
};

See Also

set message -format in Specman Command Reference

19.7.2.7 set_screen()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Starts or stops writing messages to the terminal or the Specman tab of the Console window.

Category
Method

Specman e Language Reference


1999-2015

1014

Product Version 15.1


All Rights Reserved.

Syntax
set_screen(to: message_on_off)

Parameters
to

Specifies on to start or off to stop writing messages to the terminal or Specman tab of
the Console window.

Description
By default, messages are sent to the terminal or the Specman tab of the Console window. You can use
set_screen() method to turn on and off the display of messages.

Example
The following example turns off the display of messages to the screen:
unit env_u {
my_logger: message_logger is instance;
keep soft my_logger.tags == {MY_TAG};
keep soft my_logger.verbosity == HIGH;
post_generate() is also {
my_logger.set_screen(off);
};

See Also

set message -screen in Specman Command Reference

19.7.2.8 set_style()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Specifies a color style for the message body-text.

Specman e Language Reference


1999-2015

1015
.

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
set_style(verbosity: message_verbosity, tags: list of message_tag, modules: string, text: string,
style: vt_style)

Parameters
verbosity

Specifies the verbosity level of message actions to be affected. Valid values are LOW,
MEDIUM, HIGH, and FULL.

tags

Specifies the tag, or tags, to be affected.

module

Specifies the name of the module containing the affected messages.

text

Specifies a text string. Any messages whose text matches string are affected.
The default value is ... (which matches any string; for more information, see Native
Specman String Matching on page 99.

style

Specifies a vt.text_style() color name or RGB code.

Description
Specifies the color of message text. You can use this method to color all or part of your message text.
Colors are specified by their Visual Toolkit (VT) color names, such as DARK_BLUE, or by their RGB
code, such as #00080.
Note

This method acts globally on the selected message actions, across all loggers.

Example
In the following example, the set_style() method colors in PURPLE all message text containing the
string monitoring burst in messages with the MEDIUM verbosity and the tag MY_TAG:
post_generate() is also {
sys.logger.set_style(MEDIUM, {MY_TAG}, "*", "monitoring burst",
PURPLE);
};

Specman e Language Reference


1999-2015

1016

Product Version 15.1


All Rights Reserved.

See Also

set message -style in Specman Command Reference

Using the Visualization Toolkit in Specman Deprecation and Backwards Compatability

19.7.2.9 set_trans()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Starts or stops writing structured debug messages as transactions to an SST2 database.

Category
Method

Syntax
set_trans(to: message_on_off, sst2-database: string)

Parameters
to

Specifies on to start and off to stop writing structured debug messages to an SST2
database.

sst2-database

(Optional) Specifies the name of the database directory. The default is sn_tr_db.

Description
When you writing structured debug messages to an SST2 database, you can view in them as transactions
in the Waveform window and Transaction Stripe Chart Viewer. When you turn on transaction logging,
Specman creates two files in the sst2-database directory. The sst2-database.dsn file contains design
information, and the sst2-database.trn file contains transition values. You can load these files into
SimVision in post-processing mode to view the transaction information stored there.

Specman e Language Reference


1999-2015

1017
.

Product Version 15.1


All Rights Reserved.

Example
The following example turns on transaction recording for structured debug messages by calling
set_trans() during the post_generatation phase:
unit env_u {
my_logger: message_logger is instance;
keep soft my_logger.tags == {MY_TAG};
keep soft my_logger.verbosity == HIGH;
post_generate() is also {
my_logger.set_trans(on);
};

See Also

set message -transactions in Specman Command Reference

19.7.2.10 show_actions()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Shows message actions

Category
Method

Syntax
show_actions(verbosity: message_verbosity, tags: list of string , module: string , text: string )

Parameters
verbosity

Specifies the verbosity level that for message actions handled by this handler. Valid
values are LOW, MEDIUM, HIGH, and FULL.

Specman e Language Reference


1999-2015

1018

Product Version 15.1


All Rights Reserved.

Optional Parameters
tags

Specifies the tag, or tags, to be added, replaced, or removed. The default is NORMAL.

modules

Specifies a string pattern to match the names of the modules containing the selected
messages. The default is * to match all modules.

text

Specifies a string pattern. Any messages that match the string pattern are shown. The
default is ... to match any text (for more information, see Native Specman String
Matching on page 99.

Description
Shows all message actions matching the specified parameters.
This method operates globally; not on a specific logger.

See Also

show message -actions in Specman Command Reference

19.7.2.11 show_message()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Shows information for a given message logger

Category
Method

Syntax
show_message(all:bool, full:bool)

Specman e Language Reference


1999-2015

1019
.

Product Version 15.1


All Rights Reserved.

Parameters
all

When TRUE, this method displays information about all loggers. When FALSE, the
method displays information about the current logger.

full

When TRUE, the method displays all information for the specified loggers. When
FALSE, it displays summary information about the specified loggers.

Description
Shows information for the specified logger, or loggers.

Example
The following example displays information about all loggers:
show_message(TRUE, TRUE);

The following example displays summary information about the current logger:
show_message(FALSE, FALSE);

19.7.2.12 show_units()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Shows the unit instance tree

Category
Method

Syntax
show_units(root: any_unit)

Specman e Language Reference


1999-2015

1020

Product Version 15.1


All Rights Reserved.

Parameters
root

The root unit for the instance tree

Description
Shows as a tree all unit instances under exp (default: all unit instances). For each unit, it shows which
loggers are associated with it that is, closest to the unit.
This method operates globally; not on a specific logger.

See Also

show message -units in Specman Command Reference

19.7.3

Methods for Extending accept_message() and


format_message()

Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported. If loggers are not used, you can use create_formatted message()
instead of using the format_message() method of message_logger described below. For information,
see Predefined Types Related To Messaging on page 958 and Method for User-Defined Message
Formatting on page 978.
You can use the following methods of message_logger to customize the messaging system:

The accept_message() method returns a boolean value, which determines whether a message is
output. You can extend this method to block certain types of messages. However, the message can
be enabled at runtime with the set message -action command.
The format_message() method returns a list of strings, which are output by the message. You can
extend this method to specify the format of the message itself. For example, you can use
format_message() to override the default template of a structured debug message, or to display
additional information with the message. You cannot override the new message format with the set
message -format command.

The following methods return information about the message that is currently being handled by the
message logger. These methods can be helpful when extending accept_message() and
format_message():

get_format() on page 1022

get_message() on page 1024

get_message_action_id() on page 1025

Specman e Language Reference


1999-2015

1021
.

Product Version 15.1


All Rights Reserved.

get_tag() on page 1026

get_time() on page 1026

get_verbosity() on page 1027

source_location() on page 1028

source_method_name() on page 1030

source_struct() on page 1030

source_struct_name() on page 1031

19.7.3.1 get_action_style()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Returns the vt_style for the current message action

Category
Method

Syntax
get_action_style(): vt_style

Description
Returns the vt_style name of the color being used in the message.

See Also

Using the Visualization Toolkit in Specman Deprecation and Backwards Compatability

19.7.3.2 get_format()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Specman e Language Reference


1999-2015

1022

Product Version 15.1


All Rights Reserved.

Purpose
Returns the message format of the current message logger

Category
Method

Syntax
get_format(): message_format

Description
Returns the message format, such as short, long, or none.

Example
Suppose you want to define a new message format for a particular logger. To do this, you need to define
a new message_format, assign that format to the message logger, and then extend format_message() to
recognize the format and output the message, as follows:
extend message_format: [MY_FORMAT};
.
.
.
unit env_u {
my_logger: message_logger is instance;
post_generate() is also {
my_logger.set_format(MY_FORMAT};
};
};
.
.
.
extend message_logger {
format_message(): list of string is also {
if get_format() == MY_FORMAT {
outf("sys.time is %s\n", get_time());
return {source_location(); get_message(); "\n"};
};
};
};

Specman e Language Reference


1999-2015

1023
.

Product Version 15.1


All Rights Reserved.

When you run the test, messages handled by my_logger are displayed as follows:
sys.time is 404
at line 42 in @my_simple
(ended - monitoring frame) frame-@209

19.7.3.3 get_message()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Returns the current raw message text produced by the message action

Category
Method

Syntax
get_message(): list of string

Description
The get_message() method returns the raw message textthe text output when the message format is
none.The raw message text does not include the additional information that the short and long formats
display, such as the simulation time and source code location.

Example
The following example specifies that only the raw message text should be displayed for messages with
the format, NEW_FORMAT:
extend message_logger {
format_message(): list of string is also {
if get_format() == NEW_FORMAT {
return get_message();
};
};
};

Specman e Language Reference


1999-2015

1024

Product Version 15.1


All Rights Reserved.

When you run the test, the message loggers that are configured to use the NEW_FORMAT message
format display messages only the message raw text, as follows:
(ended - monitoring frame) frame-@209

The set message -format command cannot override this message format.

19.7.3.4 get_message_action_id()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Return a unique number identifying the message action

Category
Method

Syntax
get_messag_action_id(): int

Description
Each message action has a unique ID, which is not ordinarily displayed with the message. You can use
get_message_action_id() within format_message() to display this information, if it is useful to you.

Example
The following example outputs the message action ID for each message:
extend message_logger {
format_message(): list of string is also {
outf("Message ID is %d ", get_message_action_id());
};
};

When you run the test, messages are displayed in the following format:
Message ID is 91 [359] ENV MON1 : In address phase. Sending to addr: 15

Specman e Language Reference


1999-2015

1025
.

Product Version 15.1


All Rights Reserved.

19.7.3.5 get_tag()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Returns the message tag of the message action

Category
Method

Syntax
get_tag(): message_tag

Description
Returns the message tag of the current message action.

Example
The following example calls get_tag() to look for messages with the tag, MY_TAG, and it extends
accept_message() to block messages that have that tag:
extend message_logger {
accept_message(): bool is also {
if get_tag() == MY_TAG {
return FALSE;
};
};
};

19.7.3.6 get_time()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Specman e Language Reference


1999-2015

1026

Product Version 15.1


All Rights Reserved.

Purpose
Returns the value of sys.time

Category
Method

Syntax
get_time(): string

Description
The get_time() method returns the current value of sys.time. You can use this method to include the
current time in a message format that you define.

Example
The following example defines a message format that includes only the value of sys.time and the raw
message text:
extend message_logger {
format_message(): list of string is also {
return {get_time(); get_message(); "\n"};
};
};

When you run the test, messages are displayed in the following format:
400
(ended - monitoring frame) frame-@207

19.7.3.7 get_verbosity()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Returns the verbosity of the message action

Specman e Language Reference


1999-2015

1027
.

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
get_verbosity(): message_verbosity

Description
Returns verbosity of the current messageNONE, LOW, MEDIUM, or HIGH.

Example
Suppose you want to block messages with the verbosity level of HIGH. You can do this by extending the
accept_message() method, as follows:
extend message_logger {
accept_message(): bool is also {
if get_verbosity() == HIGH {
return FALSE;
};
};
};

By default, accept_message() returns TRUE, which allows the message to be output. This example
extends accept_message() to return FALSE when the verbosity of the message is HIGH. However, this
can be overridden at runtime by the set message -verbosity command.

19.7.3.8 source_location()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Returns the source location where the message occurred

Category
Method

Specman e Language Reference


1999-2015

1028

Product Version 15.1


All Rights Reserved.

Syntax
source_location(): string

Description
The source_location() method returns the line number and name of the e module in which the message
was emitted. For example:
at line 72 in @my_simple

When the message is displayed in the Specman tab of the Console window, the source location is a hot
link to the source code. When you click on the link, the source file is opened in the Source Browser, and
a blue arrow points to the line.

Example
To include the source code location in your message format, call source_location() in the method body,
or include it in the return value.
For example, the following code displays the source location from inside the method body:
extend message_logger {
format_message(): list of string is also {
outf("Source location is %s\n", source_location());
};
};

In this example, the source location is displayed in addition to the standard message, as in the following:
Source location is at line 72 in @my_simple
[403] ENV MON2 : In address phase. Sending to addr: 10

To return the source location as part of the return value, include the call to source_location() as part of
a list of strings. For example:
extend message_logger {
format_message(): list of string is also {
return {get_message(); source_location()};
};
};

In this example, the message text and source location are displayed, as follows:
In address phase. Sending to addr: 10
at line 72 in @my_simple

Specman e Language Reference


1999-2015

1029
.

Product Version 15.1


All Rights Reserved.

19.7.3.9 source_method_name()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Returns the name of the method where the message occurred

Category
Method

Syntax
source_method_name(): string

Description
Returns the name of the method in which the message is emitted. Ordinarily, this information is
displayed only when the message format is set to long.

Example
The following example defines a message format that include the method name:
extend message_logger {
format_message(): list of string is also {
outf("Source method name is %s", source_method_name());
};
};

When messages are displayed, they include the source method name followed by the message text, as
follows:
Source method name is send_to_bfm
[370] ENV SD2 : Sending new burst of type: INFO

19.7.3.10 source_struct()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.
Specman e Language Reference
1999-2015

1030

Product Version 15.1


All Rights Reserved.

Purpose
Returns the actual source struct where the message occurred

Category
Method

Syntax
source_struct(): any_struct

Description
The source_struct() method returns the instance handle of the struct in which the message occurred.
Ordinarily, this information is returned only when the message format is set to long.

Example
The following example defines a message format that includes the instance handle of the struct in which
the message occurred:
extend message_logger {
format_message(): list of string is also {
outf("Source struct is %s", source_struct());
};
};

When messages are displayed, they include the source struct instance handle followed by the message
text, as follows:
Source struct is burst_driver-@2
[370] ENV SD2 : Sending new burst of type: INFOs

19.7.3.11 source_struct_name()
Note The documentation in this section was prepared for an older, logger-based messaging system.
Although that system is still currently supported, it is being deprecated over time and at some point in a
future release, it will not be supported.

Purpose
Returns the name of the struct type where the message occurred

Specman e Language Reference


1999-2015

1031
.

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
source_struct_name(): string

Description
The source_struct_name() method returns the name of the struct in which the message occurred.
Ordinarily, this information is not returned.

Example
The following example defines a message format that includes the name of the struct in which the
message occurred:
extend message_logger {
format_message(): list of string is also {
outf("Source struct name is %s", source_struct_name());
};
};

When messages are displayed, they include the source struct name followed by the raw message text, as
follows:
Source struct name is burst_driver
[370] ENV SD2 : Sending new burst of type: INFOs

Specman e Language Reference


1999-2015

1032

Product Version 15.1


All Rights Reserved.

20

Packing and Unpacking

Packing performs concatenation of scalars, strings, list elements, or struct fields in the order that you
specify. Unpacking performs the reverse operation, splitting a single expression into multiple
expressions.
As part of the concatenation or splitting process, packing and unpacking also perform type conversion
between any of the following:

scalars

strings

lists and list subtypes (same type but different width)

reals

For type conversion, Specman provides additional techniques. Here are some general recommendations
on when to use each technique:
as_a()

Recommended for converting a single scalar to another scalar type, for


example, from a 32-bit integer to an 8-bit integer. It is also recommended
for conversion between strings and lists of ASCII bytes. For more
information, see as_a() on page 194.

sublisting with [..]

Recommended for converting a single scalar to a list of bit. For more


information, see Chapter 1 e Basics.

bit extraction with [:]

Recommended for converting a list of bit into a single scalar. For more
information, see Chapter 1 e Basics.

unpacking

Recommended for converting from a list of bit to strings, lists, structs, or


multiple scalars.

packing

Recommended for all other purposes.

This chapter contains the following sections

Specman e Language Reference


1999-2015

1033
.

Product Version 15.1


All Rights Reserved.

Basic Packing on page 1034

Advanced Packing on page 1044

How to Debug Packing on page 1058

Constructs for Packing and Unpacking on page 1058

20.1 Basic Packing


Packing and unpacking operate on scalars, strings, lists and structs. The following sections show how to
perform basic packing and unpacking of these data types using two of Specmans basic packing tools,
the pack() and unpack() methods.

A Simple Example of Packing on page 1034

A Simple Example of Unpacking on page 1036

Packing and Unpacking Scalar Expressions on page 1038

Packing and Unpacking Strings on page 1039

Packing and Unpacking Structs on page 1040

Packing and Unpacking Lists on page 1041

For information on two other basic tools for packing, see:

%{... , ...} on page 115

swap() on page 1069

See Also

Advanced Packing on page 1044

How to Debug Packing on page 1058

Constructs for Packing and Unpacking on page 1058

20.1.1

A Simple Example of Packing

This example shows how packing converts data from a struct into a stream of bits. An instruction
struct is defined as:
struct instruction {
%opcode
: uint (bits : 3);
%operand
: uint (bits : 5);
%address
: uint (bits : 8);
!data_packed_high : list of bit;

Specman e Language Reference


1999-2015

1034

Product Version 15.1


All Rights Reserved.

!data_packed_low

: list of bit;

keep opcode == 0b100;


keep operand == 0b11001;
keep address == 0b00001111;
};

The post_generate() method of this struct is extended to pack the opcode and the operand fields
into two variables. The order in which the fields are packed is controlled with the packing.low and
packing.high options:
data_packed_low = pack(packing.low, opcode, operand);
data_packed_high = pack(packing.high, opcode, operand);

With the packing.low option, the least significant bit of the first expression in pack(), opcode, is
placed at index [0] in the resulting list of bit. The most significant bit of the last expression, operand,
is placed at the highest index in the resulting list of bit. Figure 20-1 on page 1035 shows this packing
order.
packing.low is the default packing order.
Figure 20-1

Simple Packing Example Showing packing.low

The instruction struct with two fields:


opcode == 0x4
operand == 0x19

1 0
1

1 0

0 1

The two fields packed into a bit stream, using the default ordering

operand

opcode

1 0

1 0

0 1

list of bit [7]

0
list of bit [0]

With packing.high, the least significant bit of the last expression, operand, is placed at index [0] in the
resulting list of bit. The most significant bit of the first expression, opcode, is placed at the highest
index in the resulting list of bit. Figure 20-2 shows this packing order.

Specman e Language Reference


1999-2015

1035
.

Product Version 15.1


All Rights Reserved.

Figure 20-2

Simple Packing Example Showing packing.high

The instruction struct with two fields:


opcode == 0x4

1 0
1

operand == 0x19

1 0

0 1

The two fields packed into a bit stream, using the packing.high ordering
opcode
1

0 0

operand
1

list of bit [7]

1
list of bit [0]

Pack expressions, like the ones shown in the example above, are untyped expressions. In many cases, as
in this example, Specman can deduce the required type from the context of the pack expression. See
Untyped Expressions on page 166 for more information.

See Also

A Simple Example of Unpacking on page 1036

Packing and Unpacking Scalar Expressions on page 1038

Packing and Unpacking Strings on page 1039

Packing and Unpacking Structs on page 1040

Packing and Unpacking Lists on page 1041

20.1.2

A Simple Example of Unpacking

This example shows how packing fills the fields of a struct instance with data from a bit stream. An
instruction struct is defined as:
struct instruction {
%opcode
: uint (bits : 3);
%operand
: uint (bits : 5);
%address
: uint (bits : 8);
};

The extension to post_generate() shown below unpacks a list of bits, packed_data, into a variable
inst of type instruction using the packing.high option. The results are shown in Figure 20-3.
Specman e Language Reference
1999-2015

1036

Product Version 15.1


All Rights Reserved.

extend sys {
post_generate() is also {
var inst : instruction;
var packed_data: list of bit;
packed_data = {1;1;1;1;0;0;0;0;1;0;0;1;1;0;0;1};
unpack(packing.high, packed_data, inst);
};
};

Figure 20-3

Simple Unpacking Example Showing packing.high

The packed data


1

0 0

1 1 0

0 1

0 0

0 1

1 1

The result of unpacking the data with packing.high:

opcode == 0x4

1 0

operand == 0x19

1 0

0 1

address == 0x0f

0 0

0 1 1

1 1

In this case, the expression that provides the value, packed_data, is a list of bits. When a value
expression is not a list of bit, Specman uses implicit packing to store the data in the target expression.
See Implicit Packing and Unpacking on page 1057 for more details.

See Also

A Simple Example of Packing on page 1034

Packing and Unpacking Scalar Expressions on page 1038

Packing and Unpacking Strings on page 1039

Packing and Unpacking Structs on page 1040

Packing and Unpacking Lists on page 1041

Specman e Language Reference


1999-2015

1037
.

Product Version 15.1


All Rights Reserved.

20.1.3

Packing and Unpacking Scalar Expressions

Packing a scalar expression creates an ordered bit stream by concatenating the bits of the expression
together. Unpacking a bit stream into a scalar expression fills the scalar expression, starting by default
by putting the lowest bit of the bit stream into the lowest bit of the scalar expression.
Packing and unpacking of a scalar expression is performed using the expressions inherent size, except
when the expression contains a bit slice operator. Missing bits are assumed to be zero, and extra bits are
allowed and ignored. See Scalar Types on page 138 for information on how the size of a scalar
expression is determined. See also Bit Slice Operator and Packing on page 1056.
Note

Items of type set cannot be packed or unpacked.

Packing Values for real Types


Real values take up 64 bits when packed. These bits are actual bit representation of the double value.
The effect of the various packing options on real type objects is similar to their effect on an integer
(bits:64) value.

Example
The example below packs two integers, int_5 and int_2 and then unpacks a new list of bit lob into
the same two integers. In the unpack action, the first five bits of lob are assigned to int_5 and the
next two to int_2. The remaining bits in lob are not used.
var int_5: int(bits:5) = 3;
var int_2: int(bits:2);
print pack(packing.low, int_5, int_2) using bin;
var lob:list of bit = {1;1;1;1;1;1;0;0;0;0;1;0;0;};
unpack(packing.low,lob,int_5,int_2);
print int_5, int_2;

Result
pack(packing.low, int_5, int_2) = (7 items, bin):
0 0 0

0 0 1 1

.0

int_5 = 31
int_2 = 1

Note
If you unpack a list into one or more scalar expressions and there are not enough bits in the list to put a
value into each scalar, a runtime error is issued.

Specman e Language Reference


1999-2015

1038

Product Version 15.1


All Rights Reserved.

See Also

A Simple Example of Packing on page 1034

A Simple Example of Unpacking on page 1036

Packing and Unpacking Strings on page 1039

Packing and Unpacking Structs on page 1040

Packing and Unpacking Lists on page 1041

20.1.4

Packing and Unpacking Strings

Packing a string creates an ordered bit stream by concatenating each ASCII byte of the string together
from left to right ending with a byte with the value zero (the final NULL byte). Unpacking a string
places the bytes of the string into the target expression, starting with the first ASCII byte in the string up
to and including the first byte with the value zero.
To obtain different results, you can use the as_a() method, which converts directly between the string
and list of byte types. See as_a() on page 194 for more information.

Example
In this example, the packed string is implicitly unpacked into a list of byte.
The last byte is zero since it is the final NULL byte.
var my_string: string = "ABC";
print pack(packing.low, my_string);
var my_list_of_byte: list of byte = pack(packing.low, my_string);
print my_list_of_byte using hex;

Result
pack(packing.low,my_string) = (32 items, hex):
0 0 4 3

4 2 4 1

.0

my_list_of_byte = (4 items, hex):


00 43 42 41

.0

See Also

A Simple Example of Packing on page 1034

A Simple Example of Unpacking on page 1036

Packing and Unpacking Scalar Expressions on page 1038

Specman e Language Reference


1999-2015

1039
.

Product Version 15.1


All Rights Reserved.

Packing and Unpacking Structs on page 1040

Packing and Unpacking Lists on page 1041

20.1.5

Packing and Unpacking Structs

Packing a struct creates an ordered bit stream from all the physical fields (marked with %) in the struct,
starting by default, with the first physical field declared. Other fields (called virtual fields) are ignored
by the packing process. If a physical field is of a compound type (struct or list) the packing process
descends recursively into the struct or list.
Unpacking a bit stream into a struct fills the physical fields of the struct, starting by default with the first
field declared and proceeding recursively through all the physical fields of the struct. Unpacking a bit
stream into a field that is a list follows some additional rules described in Packing and Unpacking Lists
on page 1041.
Unpacking a struct that has not yet been allocated (with new) causes Specman to allocate the struct and
run the structs init() method. Unlike new, the structs run() method is not called.
A struct is packed or unpacked using its predefined methods do_pack() and do_unpack(). It is possible
to modify these predefined methods for a particular struct. See do_pack() on page 1071 and
do_unpack() on page 1075 for more information.

Example
This example packs the two physical fields in my_struct into the variable ms. The resulting bit
stream is 14 bits, which is exactly the combination of both the physical fields. The virtual field int_15
does not participate in the pack process at all.
struct my_struct{
%int_4: int(bits:4);
%int_10: int(bits:10);
int_15: int(bits:15);
init() is also {
int_4 = 3;
int_10 = 15;
};
};
struct pac {
m() is {
var ms: my_struct = new;
print pack(packing.low, ms) using hex;
};
};

Specman e Language Reference


1999-2015

1040

Product Version 15.1


All Rights Reserved.

Result
pack(packing.low,ms) = (14 items, bin):
0 0 0 0 0 0

1 1 1 1

0 0 1 1

.0

See Also

A Simple Example of Packing on page 1034

A Simple Example of Unpacking on page 1036

Packing and Unpacking Scalar Expressions on page 1038

Packing and Unpacking Strings on page 1039

Packing and Unpacking Lists on page 1041

20.1.6

Packing and Unpacking Lists

Packing a list creates a bit stream by concatenating the list items together, starting by default with the
item at index 0.
Unpacking a bit stream into a list fills the list item by item, starting by default with the item at index
zero. The size of the list that is unpacked into is determined by whether the list is sized and whether it is
empty:

Unpacking into an empty list expands the list as needed to contain all the available bits.

Unpacking into a non-empty list unpacks only until the existing list size is reached.

Unpacking to a struct fills the sized lists only to their defined size, regardless of their actual size at
the time.

Note When a struct is allocated, the lists within it are empty. If the lists are sized, unpacking is
performed until the defined size is reached.
See Chapter 1 e Basics, for more information on sizing lists.

Example 1
This first example shows the effect of packing a list of integers.
var my_list: list of int(bits:4) = {3;5;7;9;11;13;15};
print pack(packing.low,my_list);

Result
pack(packing.low,my_list) = (28 items, hex):
f d b

Specman e Language Reference


1999-2015

1041
.

9 7 5 3

.0

Product Version 15.1


All Rights Reserved.

Example 2
The list my_list is empty, so it is expanded to contain all 32 bits of the integer.
var my_list: list of int(bits:4);
unpack(packing.low,5,my_list);
print my_list using hex;

Result
my_list = (8 items, hex):
0

.0

Example 3
The list was not empty because it was initialized to have four items. Thus it is not expanded and the
resulting list has four items.
var my_list: list of int(bits:4) = {0;0;0;0};
unpack(packing.low,5,my_list);
print my_list using hex;

Result
my_list = (4 items, dec):
0

.0

Example 4
The my_list field is cleared in order to demonstrate that although the procedural code has corrupted
the lists initial size, it is restored when unpack is performed.
struct my_struct{
%my_list[4]: list of int(bits:4);
};
struct pac {
m() is {
var t:my_struct = new;
t.my_list.clear();
print t.my_list;
unpack(packing.low,5,t);
print t.my_list;
};
};

Specman e Language Reference


1999-2015

1042

Product Version 15.1


All Rights Reserved.

Result
t.my_list = (empty)
t.my_list = (4 items, hex):
0 0 0 5

.0

Example 5
Unpacking into an unsized, uninitialized list causes a runtime error message because the list is expanded
as needed to consume all the given bits. The field int_1 remains bit-less.
struct my_struct{
%my_list: list of int(bits:4);
%int_1: bit;
};
struct pac {
m() is {
var t:my_struct = new;
unpack(packing.low,5,t);
};
};

Example 6
This example shows the recommended way to get a variable number of list items. The specification
order is important because the len1 and len2 values must be set before initializing data1 and
data2. Declaring len1 and len2 before data1 and data2 ensures that the list length is generated
first. When unpacking into a list with a variable number of items, you will have to calculate the number
of items in the list before unpacking. See do_unpack() on page 1075 for an example of how to do this.
struct packet{
%len1: int;
%len2: int;
%data1[len1]: list of byte;
%data2[len1 + len2]: list of byte;
};

See Also

A Simple Example of Packing on page 1034

A Simple Example of Unpacking on page 1036

Packing and Unpacking Scalar Expressions on page 1038

Packing and Unpacking Strings on page 1039

Specman e Language Reference


1999-2015

1043
.

Product Version 15.1


All Rights Reserved.

Packing and Unpacking Structs on page 1040

20.2 Advanced Packing


The following sections describe how to use the Specman advanced packing features and provide you
with the concepts you need to use them efficiently:

Using the Predefined pack_options Instances on page 1044

Customizing Pack Options on page 1050

Customizing Packing for a Particular Struct on page 1056

Bit Slice Operator and Packing on page 1056

Implicit Packing and Unpacking on page 1057

Untyped Expressions on page 166

See Also

Basic Packing on page 1034

How to Debug Packing on page 1058

Constructs for Packing and Unpacking on page 1058

20.2.1

Using the Predefined pack_options Instances

Packing and unpacking are controlled using a struct under global named packing. There are five
predefined instances of the pack_options struct that you can use with or without modification to control
the way packing or unpacking is performed. You are probably familiar with two of these pack_options
instances, packing.low and packing.high.
When you call pack(), unpack(), do_pack() or do_unpack() you pass one of the predefined
pack_options instances as the first parameter. In the example below, packing.high is passed as the
pack_options instance:
data_packed_high = pack(packing.high, opcode, operand);

The following sections describe the pack_options instances:

packing.low on page 1045

packing.low_big_endian on page 1046

packing.high on page 1047

packing.high_big_endian on page 1048

packing.network on page 1049

Specman e Language Reference


1999-2015

1044

Product Version 15.1


All Rights Reserved.

packing.global_default on page 1050

See Also

Customizing Pack Options on page 1050

Customizing Packing for a Particular Struct on page 1056

Bit Slice Operator and Packing on page 1056

Implicit Packing and Unpacking on page 1057

Untyped Expressions on page 166

20.2.1.1 packing.low
This pack_options instance traverses the source fields or variables in the order they appear in code,
placing the least significant bit of the first field or list item at index [0] in the resulting list of bit. The
most significant bit of the last field or list item is placed at the highest index in the resulting list of bit.
<'
struct instruction {
%opcode
: uint (bits : 3);
%operand
: uint (bits : 5);
%address
: uint (bits : 8);
!data_packed_low : list of bit;
keep opcode == 0b100;
keep operand == 0b11001;
keep address == 0b00001111;
post_generate() is also {
data_packed_low = pack(packing.low, me);
print me using bin;
print data_packed_low using bin;
};
};
'>

Result
me = instruction-@0: instruction
@packing20
0
1
2
3

%opcode:
%operand:
%address:
!data_packed_low:

Specman e Language Reference


1999-2015

0b100
0b11001
0b00001111
(16 items)
1045
.

Product Version 15.1


All Rights Reserved.

data_packed_low = (16 items, bin):


0 0 0 0 1 1 1 1

1 1 0 0

1 1 0 0

.0

See Also

Using the Predefined pack_options Instances on page 1044

20.2.1.2 packing.low_big_endian
This pack_options instance, like packing.low, traverses the source fields or variables in the order they
appear in code. In addition, for every scalar field or variable, it

Swaps every byte in each pair of bytes

Swaps every two bytes in each 32-bit word

Notes

If the scalars width is not a multiple of 16, no swapping is performed.


The packing.low_big_endian scalar reordering rule is {8;16;16;32}. You can create a customized
packing option to support 64-bit. See scalar_reorder on page 1052 for an example.

The example below shows the difference between packing.low and packing.low_big_endian.
struct pac {
%opcode: uint (bits:4);
%operand1: uint (bytes:2);
%operand2: uint (bytes:2);
keep opcode == 0xf;
keep operand1 == 0xcc55;
keep operand2 == 0xff00;
m() is {
var i_stream: list of bit;
i_stream = pack(packing.low, opcode,
operand1, operand2);
print i_stream using bin;
i_stream = pack(packing.low_big_endian, opcode,
operand1, operand2);
print i_stream using bin;
};
};

Result
i_stream = (36 items, bin):
Specman e Language Reference
1999-2015

1046

Product Version 15.1


All Rights Reserved.

0 0 0 0

1 1 0 0

1 1 0 0

i_stream = (36 items, bin):


1 1 1 1 0 1 0 1 0 1 0 1

0 1 0 1
1 1 1 1

0 1 0 1
1 1 1 1

1 1 1 1
0 0 0 0

.0
.24

1 1 0 0
0 0 0 0

1 1 0 0
0 0 0 0

1 1 1 1
1 1 1 1

.0
.24

See Also

Using the Predefined pack_options Instances on page 1044

20.2.1.3 packing.high
This pack_options instance traverses the source fields or variables in the reverse order from the order in
which they appear in code, placing the least significant bit of the last field or list item at index [0] in the
resulting list of bit. The most significant bit of the first field or list item is placed at the highest index in
the resulting list of bit.
<'
struct instruction {
%opcode
: uint (bits : 3);
%operand
: uint (bits : 5);
%address
: uint (bits : 8);
!data_packed_high : list of bit;
keep opcode == 0b100;
keep operand == 0b11001;
keep address == 0b00001111;
post_generate() is also {
data_packed_high = pack(packing.high, opcode, operand);
print me using bin;
print data_packed_high using bin;
};
};
'>

Result
me = instruction-@0: instruction
@packing18
0
1
2
3

%opcode:
%operand:
%address:
!data_packed_high:

Specman e Language Reference


1999-2015

0b100
0b11001
0b00001111
(8 items)
1047
.

Product Version 15.1


All Rights Reserved.

data_packed_high = (8 items, bin):


1 0 0 1

1 0 0 1

.0

See Also

Using the Predefined pack_options Instances on page 1044

20.2.1.4 packing.high_big_endian
This pack_options instance, like packing.high, traverses the source fields or variables in the reverse
order from the order in which they appear in code. In addition, for every scalar field or variable, it

Swaps every byte in each pair of bytes

Swaps every two bytes in each 32-bit word

Notes

If the scalars width is not a multiple of 16, no swapping is performed.


The packing.high_big_endian scalar reordering rule is {8;16;16;32}. You can create a customized
packing option to support 64-bit. See scalar_reorder on page 1052 for an example.

The example below shows the difference between packing.high and packing.high_big_endian.
struct pac {
%opcode: uint (bits:4);
%operand1: uint (bytes:2);
%operand2: uint (bytes:2);
keep opcode == 0xf;
keep operand1 == 0xcc55;
keep operand2 == 0xff00;
m() is {
var i_stream: list of bit;
i_stream = pack(packing.high, opcode,
operand1,operand2);
print i_stream using bin;
i_stream = pack(packing.high_big_endian, opcode,
operand1,operand2);
print i_stream using bin;
};
};

Result
i_stream = (36 items, bin):
Specman e Language Reference
1999-2015

1048

Product Version 15.1


All Rights Reserved.

0 1 0 1

0 1 0 1

1 1 1 1

i_stream = (36 items, bin):


1 1 0 0 1 1 0 0 0 0 0 0

1 1 1 1
1 1 1 1

0 0 0 0
1 1 0 0

0 0 0 0
1 1 0 0

.0
.24

0 0 0 0
1 1 1 1

1 1 1 1
0 1 0 1

1 1 1 1
0 1 0 1

.0
.24

See Also

Using the Predefined pack_options Instances on page 1044

20.2.1.5 packing.network
This packing option is the same as packing.high if the total number of bits that will comprise the target
is not a multiple of 8. When it is a multiple of 8, then the target bits of the entire bit stream are byte-order
reversed.
<'
struct instruction {
%opcode
: uint (bits : 3);
%operand
: uint (bits : 5);
%address
: uint (bits : 8);
!data_packed_high : list of bit;
!data_packed_network : list of bit;
keep opcode == 0b100;
keep operand == 0b11001;
keep address == 0b00001111;
post_generate() is also {
data_packed_high = pack(packing.high, opcode, operand,
address);
data_packed_network = pack(packing.network, opcode,
operand, address);
print me using bin;
print data_packed_high using bin;
print data_packed_network using bin;
};
};
'>

Results
cmd-prompt> gen
Specman e Language Reference
1999-2015

1049
.

Product Version 15.1


All Rights Reserved.

Doing setup ...


Generating the test using seed 1...
me = instruction-@0: instruction
---------------------------------------------- @packing13
0
%opcode:
0b100
1
%operand:
0b11001
2
%address:
0b00001111
3
!data_packed_high:
(16 items)
4
!data_packed_network:
(16 items)
data_packed_high = (16 items, bin):
1 0 0 1 1 0 0 1 0 0 0 0 1 1 1 1
.0
data_packed_network =

(16 items, bin):


0 0 0 0 1 1 1 1

1 0 0 1

1 0 0 1

.0

20.2.1.6 packing.global_default
This pack_options instance is used when the first parameter of pack(), unpack(), do_pack(), or
do_unpack() is NULL. It has the same flags as packing.low.

See Also

Using the Predefined pack_options Instances on page 1044

20.2.2

Customizing Pack Options

Each of the predefined instances described in Using the Predefined pack_options Instances on page
1044 is an instance of the pack_options struct. The pack_options declaration is as follows:
struct pack_options {
reverse_fields: bool;
reverse_list_items: bool;
final_reorder: list of int;
scalar_reorder: list of int;
};

To customize packing options, you can create an instance of the pack_options struct, modify one or
more of its fields, and pass the struct instance as the first parameter to pack(), unpack(), do_pack(), or
do_unpack().
The following sections describe each field of the pack_options struct:

reverse_fields on page 1051

reverse_list_items on page 1052

scalar_reorder on page 1052

Specman e Language Reference


1999-2015

1050

Product Version 15.1


All Rights Reserved.

final_reorder on page 1054

See Also

Using the Predefined pack_options Instances on page 1044

Customizing Packing for a Particular Struct on page 1056

Bit Slice Operator and Packing on page 1056

Implicit Packing and Unpacking on page 1057

Untyped Expressions on page 166

20.2.2.1 reverse_fields
If this flag is set to be FALSE, the fields in a struct are packed in the order they appear in the struct
declaration; if TRUE, they are packed in reverse order. The default is FALSE.

Example
When reverse_fields is FALSE, first is packed and then second. When the flag is set to TRUE,
second is packed before first. Thus, the first result is 0b01; the second result is 0b10.
struct my_struct{
%first :int(bits:1); -- value 1
%second :int(bits:1); -- value 0;
init() is also {
first = 1;
};
};
extend sys{
my_struct;
foo() is {
var p1:pack_options = new;
var p2:pack_options = new;
p2.reverse_fields = TRUE;
my_struct = new;
print pack(p1,my_struct);
print pack(p2,my_struct);
};
};

Result
pack(p1,my_struct) = (2 items, hex):
1
Specman e Language Reference
1999-2015

1051
.

.0
Product Version 15.1
All Rights Reserved.

pack(p2,my_struct) = (2 items, hex):


2

.0

See Also

Customizing Pack Options on page 1050

20.2.2.2 reverse_list_items
If this flag is set to be FALSE, the items in a list are packed in ascending order; if TRUE, they are packed
in descending order. The default is FALSE.

Example
The second print statement shows that my_list is packed in reverse order.
var my_list:list of int(bits:1) = {1;0;0};
var p1:pack_options = new;
var p2:pack_options = new;
p2.reverse_list_items = TRUE;
print pack(p1,my_list) using bin;
print pack(p2,my_list) using bin;

Result
pack(p1,my_list) = (3 items, bin):
0 0 1

.0

1 0 0

.0

pack(p2,my_list) = (3 items, bin):

See Also

Customizing Pack Options on page 1050

20.2.2.3 scalar_reorder
You can perform one or more swap() operations on each scalar before packing using the scalar_reorder
field.
The list in the scalar_reorder field must include an even number of items. Each pair of items in the list
is the parameter list of a swap() operation (see swap() on page 1069). By entering multiple pairs of
parameters, you can perform multiple swaps, using each pair of parameters as a pair of swap parameters.

Specman e Language Reference


1999-2015

1052

Product Version 15.1


All Rights Reserved.

Unlike swap(), if the large parameter is not a factor of the number of bits in the list, scalar_reorder
ignores it, while swap() gives an error.

Example 1
The bits in mid and sma are swapped using 4 and 2 as parameters. See swap() on page 1069. Thus,
within every four bits the first two bits and the last two are swapped.
var p1:pack_options = new;
var mid:int(bits:8) = 0xcc;
var sma:int(bits:4) = 0x6;
print pack(p1,mid) using bin;
print pack(p1,sma) using bin;
p1.scalar_reorder = {2;4};
print pack(p1,mid) using bin;
print pack(p1,sma) using bin;

Result
pack(p1,mid) = (8 items, bin):
1 1 0 0

1 1 0 0

.0

0 1 1 0

.0

0 0 1 1

.0

1 0 0 1

.0

pack(p1,sma) = (4 items, bin):

pack(p1,mid) = (8 items, bin):


0 0 1 1
pack(p1,sma) = (4 items, bin):

Example 2
The bits in midb are swapped, first using 8 and 4 as parameters, and then using 16 and 8 as parameters.
See swap() on page 1069. Thus, within every eight bits the first four bits and the last four are swapped,
and then within the entire 16-bit number, the first eight bits and the last eight bits are swapped.
var p1:pack_options = new;
var midb:int(bits:16) = 0xc5fd;
print pack(p1,midb) using bin;
p1.scalar_reorder = {4;8;8;16};
print pack(p1,midb) using bin;

Result
pack(p1,midb) =

(16 items, bin):

Specman e Language Reference


1999-2015

1053
.

Product Version 15.1


All Rights Reserved.

pack(p1,midb) =

Example 3

1 1 0 0

0 1 0 1

1 1 1 1

1 1 0 1

.0

(16 items, bin):


1 1 0 1

1 1 1 1

0 1 0 1

1 1 0 0

.0

64-bit Packing High/Low Big Endian

The packing.high_big_endian and packing.low_big_endian scalar reordering rule is {8;16;16;32}.


You can create an option as shown below to support 64 bit by setting scalar_reorder to be
{8;16;16;32;32;64}.
<'
extend sys {
run() is also {
var q1 : uint (bits: 64) = 0X0807060504030201;
var q2 : uint (bits: 64);
print q1 using hex;
var p: pack_options = packing.high_big_endian.copy();
p.scalar_reorder = {8;16;16;32;32;64};
q2 = pack(packing.high_big_endian, q1);
print q2 using hex;
q2 = pack(p, q1);
print q2 using hex;
};
};
'>

Result
Starting the test ...
Running the test ...
q1 = 0x0807060504030201
q2 = 0x0506070801020304
q2 = 0x0102030405060708
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

Customizing Pack Options on page 1050

20.2.2.4 final_reorder
After packing each element in the packing expression you can perform final swapping on the resulting
bit stream, using the final_reorder field.
Specman e Language Reference
1999-2015

1054

Product Version 15.1


All Rights Reserved.

The list in the final_reorder field must include an even number of items. Each pair of items in the list is
the parameter list of a swap() operation (see swap() on page 1069). By entering multiple pairs of
parameters, you can perform multiple swaps, using each pair of parameters as a pair of swap parameters.
Unlike swap(), if the large parameter is not a factor of the number of bits in the list, final_reorder
ignores it, while swap() gives an error.

Example 1
After performing the second pack, a swap is performed using 4 and 8 as parameters, thus reversing the
order of nibbles in every byte. See swap() on page 1069.
var p1:pack_options = new;
var int__4: int(bits:4) = 0x7;
var int__12: int(bits:12) = 0x070;
print pack(p1,int__4,int__12) using bin;
p1.final_reorder = {4;8};
print pack(p1,int__4,int__12) using bin;

Result
pack(p1,int__4,int__12) = (16 items, bin):
0 0 0 0 0 1 1 1

0 0 0 0

0 1 1 1

.0

pack(p1,int__4,int__12) = (16 items, bin):


0 1 1 1 0 0 0 0

0 1 1 1

0 0 0 0

.0

Example 2
The bits in midb are swapped, first using 8 and 4 as parameters, and then using 16 and 8 as parameters.
See swap() on page 1069. Thus, within every eight bits the first four bits and the last four are swapped,
and then within the entire 16-bit number, the first eight bits and the last eight bits are swapped.
var p1:pack_options = new;
var midb:int(bits:16) = 0xc5fd;
print pack(p1,midb) using bin;
p1.scalar_reorder = {4;8;8;16};
print pack(p1,midb) using bin;

Result
pack(p1,midb) =

pack(p1,midb) =

(16 items, bin):


1 1 0 0

0 1 0 1

1 1 1 1

1 1 0 1

.0

(16 items, bin):


1 1 0 1

1 1 1 1

0 1 0 1

1 1 0 0

.0

Specman e Language Reference


1999-2015

1055
.

Product Version 15.1


All Rights Reserved.

See Also

Customizing Pack Options on page 1050

20.2.3

Customizing Packing for a Particular Struct

You can customize packing for a particular struct by modifying the do_pack() or do_unpack() methods
of the struct. These methods are called automatically whenever data is packed from or unpacked into the
struct. See do_pack() on page 1071 and do_unpack() on page 1075 for more information.

See Also

Using the Predefined pack_options Instances on page 1044

Customizing Pack Options on page 1050

Bit Slice Operator and Packing on page 1056

Implicit Packing and Unpacking on page 1057

Untyped Expressions on page 166

20.2.4

Bit Slice Operator and Packing

You can use the bit slice operator [ : ] to select a subrange of an expression to be packed or unpacked.
The bit slice operator does not change the type of the pack or unpack expression.

Example 1
In the following example, the result of the first print statement is 20 bits long. However, the pack
expression, which extracts only 2 bits of int_20, is only 2 bits long.
var int_20: int(bits:20) = 7;
print int_20[1:0] using bin;
print pack(packing.low,int_20[1:0]) using bin;

Result
int_20[1:0] = 0b00000000000000000011
pack(packing.low,int_20[1:0]) = (2 items, bin):
1 1

.0

Example 2
int_5 did not consume five bits as its type suggests. Because of the bit slice operator, it consumed only
two bits. Thus int_1 gets the third bit from lob and remains 0.
Specman e Language Reference
1999-2015

1056

Product Version 15.1


All Rights Reserved.

var int_5: int(bits:5);


var int_1: bit;
var lob: list of bit = {1;1;0;1;1;1;1};
unpack(packing.low, lob, int_5[1:0], int_1);
print int_5, int_1 using bin;

Result
int_5 = 0b00011
int_1 = 0b0

See Also

Using the Predefined pack_options Instances on page 1044

Customizing Pack Options on page 1050

Customizing Packing for a Particular Struct on page 1056

Implicit Packing and Unpacking on page 1057

Untyped Expressions on page 166

20.2.5

Implicit Packing and Unpacking

Implicit packing and unpacking is always performed using the parameters of packing.low and takes
place in the following cases:

When an untyped expression is assigned to a scalar or list of scalars, it is implicitly unpacked before
it is assigned.
var my_list: list of int = {1;2;3};
var int_10: int(bits:10);
my_list = 'top.foo';
int_10 = pack(NULL, 5);

Untyped expressions include HDL signals, pack expressions and bit concatenations. See Untyped
Expressions on page 166 for more information.
Note Implicit packing and unpacking is not supported for strings, structs, or lists of non-scalar
types. As a result, the following causes a load-time error if i is a string, a struct, or a list of a
non-scalar type:
i = pack(packing.low, 5);

// Load-time error

When a scalar or list of scalars is assigned to an untyped expression, it is implicitly packed before it
is assigned:
'top.foo' = {1;2;3};

Specman e Language Reference


1999-2015

1057
.

Product Version 15.1


All Rights Reserved.

When the value expression of an unpack action is other than a list of bit, it is implicitly packed before
it is unpacked:
unpack(packing.low,5,my_list);

See Also

Using the Predefined pack_options Instances on page 1044

Customizing Pack Options on page 1050

Customizing Packing for a Particular Struct on page 1056

Bit Slice Operator and Packing on page 1056

Untyped Expressions on page 166

20.3 How to Debug Packing


You can use the show pack and show unpack commands to display the results of packing or unpacking.
The trace packing command can help you debug your packing results. If you suspect that something
went wrong during packing or unpacking, you might want to set the trace pack flag. This trace follows
the packing process as it progresses and displays intermediate results to the screen.

See Also

trace on packing in the Specman Command Reference

show pack in the Specman Command Reference

show unpack in the Specman Command Reference

Basic Packing on page 1034

Advanced Packing on page 1044

Constructs for Packing and Unpacking on page 1058

20.4 Constructs for Packing and Unpacking


The following sections describe the constructs used in packing and unpacking:

pack() on page 1059

unpack() on page 1064

%{... , ...} on page 115

swap() on page 1069

do_pack() on page 1071

Specman e Language Reference


1999-2015

1058

Product Version 15.1


All Rights Reserved.

do_unpack() on page 1075

See Also

Basic Packing on page 1034

Advanced Packing on page 1044

How to Debug Packing on page 1058

20.4.1

pack()

Purpose
Perform concatenation and type conversion

Category
Pseudo-method

Syntax
pack(option:pack option, item: exp, ...): list of bit
Syntax Example
i_stream = pack(packing.high, opcode, operand1, operand2);

Parameters
option

For basic packing, this parameter is one of the following. See Using the Predefined
pack_options Instances on page 1044 for information on other pack options.

packing.high

Places the least significant bit of the last physical field declared or the highest list item
at index [0] in the resulting list of bit. The most significant bit of the first physical field
or lowest list item is placed at the highest index in the resulting list of bit.

packing.low

Places the least significant bit of the first physical field declared or lowest list item at
index [0] in the resulting list of bit. The most significant bit of the last physical field or
highest list item is placed at the highest index in the resulting list of bit.

NULL

If NULL is specified, the global default is used. This global default is set initially to
packing.low.

Specman e Language Reference


1999-2015

1059
.

Product Version 15.1


All Rights Reserved.

item

A legal e expression that is a path to a scalar or a compound data item, such as a struct,
field, list, or variable.

Description
Performs concatenation of items, including items in a list or fields in a struct, in the order specified by
the pack options parameter and returns a list of bits. This method also performs type conversion between
any of the following:

scalars
strings
lists and list subtypes (same type but different width)

Packing is commonly used to prepare high-level e data into a form that can be applied to a DUT. For
other uses, see Packing and Unpacking on page 1033.
Packing operates on scalar or compound (struct, list) data items. For more information and examples of
how packing operates on different data types, see Basic Packing on page 1034.
Pack expressions are untyped expressions and are evaluated as a list of bit by default. For example, the
following expression is evaluated as a list of bit because there is no specific data type implied in the
context:
out(pack(packing.high, foo));

In many cases, Specman can deduce the required type from the context of the pack expression. For
example, the following expressions are evaluated as a signed integer:
var tmp : int = pack(packing.high, foo);
out(pack(packing.high, foo) == 1);

If you want a pack expression to be evaluated as a specific type, assign the result of pack() into a
variable of desired type before using it.
See Untyped Expressions on page 166 for more information.

Note
You cannot pack an unbounded integer.

Example 1
The extension to post_generate() shown below packs the opcode and the operand fields of the
instruction struct from the low bit of the last field defined (operand) to the high bit of the first field
defined (opcode) into the data_packed_high field. It also packs all the physical fields into
data_packed_low using the packing.low option. The results are shown in Figure 20-4 on page 1062.
Specman e Language Reference
1999-2015

1060

Product Version 15.1


All Rights Reserved.

<'
struct instruction {
%opcode
: uint (bits : 3);
%operand
: uint (bits : 5);
%address
: uint (bits : 8);
!data_packed_high : list of bit;
!data_packed_low : list of bit;
keep opcode == 0b100;
keep operand == 0b11001;
keep address == 0b00001111;
post_generate() is also {
data_packed_high = pack(packing.high,
opcode,operand);
data_packed_low = pack(packing.low, me);
print me using bin;
print data_packed_low using bin;
print data_packed_high using bin;
};
};
'>

Specman e Language Reference


1999-2015

1061
.

Product Version 15.1


All Rights Reserved.

Figure 20-4

Packed Instruction Data

The instruction struct:


opcode == 0x4

1 0

operand == 0x19

1 0

0 1

address == 0x0f

0 1

1 1

The fields opcode and operand packed, using packing.high


operand

opcode
1

0 0

list of bit [7]

1
list of bit [0]

The instruction packed, using packing.low


address
0 0

0 0 1

1 1

operand

opcode

1 0

1 0

0 1

list of bit [15]

0
list of bit [0]

Example 2
In this example, post_generate() is extended to pack the packet data. The header field of the packet
struct is a struct itself, so this is a recursive pack. The results are shown in Figure 20-5 on page 1064.
<'
struct packet {
%header : header;
%payload : list of byte;
!data_packed_low : list of byte;
keep payload.size() == 6;
keep for each in payload {
it == index;
};

Specman e Language Reference


1999-2015

1062

Product Version 15.1


All Rights Reserved.

post_generate() is also {
data_packed_low = pack(packing.low, me);
out("payload:
", payload);
out("data packed low: ", data_packed_low);
};
};
struct header {
%dest
: int (bits : 8);
%version
: int (bits : 2);
%type
: uint (bits : 6);

keep dest == 0x55;


keep version == 0x0;
keep type == 0x3f;
post_generate() is also {
print me;
};
};
'>

Result
Note that the out() action displays the bytes from least significant to most significant (from left to
right), whereas the print action displays the bytes from most significant to least significant (from left to
right).
cmd-prompt> test
Doing setup ...
Generating the test using seed 0x1...
me = header-@0: header
--------------------------------------------- @pack23
0
%dest:
0x55
1
%version:
0x0
2
%type:
0x3f
payload
: 0x00 0x01 0x02 0x03 0x04 0x05
packet packed low: 0x55 0xfc 0x00 0x01 0x02 0x03 0x04 0x05

Specman e Language Reference


1999-2015

1063
.

Product Version 15.1


All Rights Reserved.

Figure 20-5

Packed Packet Data

The packet struct:


Header:
0 1

dest

version

0 1

0 1

1 1

type

0 1

1 1

1 1

Payload
0

0 0

0 0 1

0 1

.....

0 0

0 0 0

0 0

The packet data packed, using packing.low


payload
..... 0 0 0 0 0 0
list of bit [127]

version

type
0 0 1 1

1 1

1 1

dest
0 1

0 1

0 1

0 1

list of bit [0]

See Also

unpack() on page 1064

%{... , ...} on page 115

swap() on page 1069

do_pack() on page 1071

do_unpack() on page 1075

20.4.2

unpack()

Purpose
Unpack a bit stream into one or more expressions

Category
Pseudo-method

Specman e Language Reference


1999-2015

1064

Product Version 15.1


All Rights Reserved.

Syntax
unpack(option: pack option, value: exp, target1: exp [, target2: exp, ...])
Syntax Example
unpack(packing.high, lob, s1, s2);

Parameters
option

For basic packing, this parameter is one of the following. See Using the Predefined
pack_options Instances on page 1044 for information on other pack options.

packing.high

Places the most significant bit of the list of bit at the most significant bit of the first
field or lowest list item. The least significant bit of the list of bit is placed into the least
significant bit of the last field or highest list item.

packing.low

Places the least significant bit of the list of bit into the least significant bit of the first
field or lowest list item. The most significant bit of the list of bit is placed at the most
significant bit of the last field or highest list item.

NULL

If NULL is specified, the global default is used. This global default is set initially to
packing.low.

value

A scalar expression or list of scalars that provides a value that is to be unpacked.

target1, target2

One or more expressions separated by commas. Each expression is a path to a scalar


or a compound data item, such as a struct, field, list, or variable.

Description
Converts a raw bit stream into high level data by storing the bits of the value expression into the target
expressions.
If the value expression is not a list of bit, it is first converted into a list of bit by calling pack() using
packing.low. (See Implicit Packing and Unpacking on page 1057 for more information.) Then the list
of bit is unpacked into the target expressions.
The value expression is allowed to have more bits than are consumed by the target expressions. In that
case, if packing.low is used, the extra high-order bits are ignored; if packing.high is used, the extra
low-order bits are ignored.
Unpacking is commonly used to convert raw bit stream output from the DUT into high-level e data.
Unpacking operates on scalar or compound (struct, list) data items. For more information and examples
of how packing operates on different data types, see Basic Packing on page 1034.

Specman e Language Reference


1999-2015

1065
.

Product Version 15.1


All Rights Reserved.

Example 1
The extension to post_generate() shown below unpacks a list of bits into a variable inst. The results
are shown in Figure 20-6 on page 1066.
extend sys {
post_generate() is also {
var inst : instruction;
var packed_data: list of bit;
packed_data = {1;1;1;1;0;0;0;0;1;0;0;1;1;0;0;1};
unpack(packing.high, packed_data, inst);
print packed_data using bin;
out("the result of unpacking it: ");
print inst using bin;
};
};
struct instruction {
%opcode
: uint (bits : 3);
%operand
: uint (bits : 5);
%address
: uint (bits : 8);
};

Figure 20-6

Unpacked Instruction Data

The packed data


1

0 0

1 1 0

0 1

0 0

0 1

1 1

The result of unpacking the data with packing.high:

opcode == 0x4

1 0

operand == 0x19

1 0

0 1

address == 0x0f

0 0

0 1 1

Specman e Language Reference


1999-2015

1 1

1066

Product Version 15.1


All Rights Reserved.

Example 2
The extension to post_generate() shown below unpacks a list of bytes into a variable pkt using
packing.low. This is a recursive unpack because the header field of packet is a struct itself. The
results are shown in Figure 20-7 on page 1068.
extend sys {
post_generate() is also {
var pkt : packet;
var packed_data : list of byte;
packed_data =
{0x55;0xfc;0x00;0x01;0x02;0x03;0x04;0x05};
unpack(packing.low, packed_data, pkt);
print packed_data;
out("the unpacked struct:");
print pkt.header, pkt.payload;
};
};
struct packet {
%header : header;
%payload : list of byte;
};
struct header {
%dest
: int (bits : 8);
%version
: int (bits : 2);
%type
: int (bits : 6);
};

Specman e Language Reference


1999-2015

1067
.

Product Version 15.1


All Rights Reserved.

Figure 20-7

Unpacked Packet Data

The packed data


..... 0 0 0 0

0 0

0 0

1 1 1 1 1 1

0 0

0 1 0 1 0 1 0 1

The unpacked struct

Header:
dest
version
type

0 1 0 1

0 1

0 1

0 0
1 1 1 1

1 1

Payload
0 0 0 0 0 1 0 1

.....

0 0 0 0 0 0 0 0

Example 3
This example uses unpack() sequentially to set up virtual fields that are required for the full unpack.
struct packet {
%header: header;
len : uint;
%data[len] : list of byte;
};
struct header {
%code : uint;
};
extend sys {
m() is {
var DUT_bytes: list of byte = {0x11;0xff;0x22;
0xee;0x33;0xdd;0x44;0xcc;0x55;0xbb;0x66};
var p : packet = new;
unpack(packing.low, DUT_bytes, p.header);
if p.header.code > 1500 {
p.len = 10;
} else {
p.len = 20;
};
unpack(packing.low, DUT_bytes,p);
Specman e Language Reference
1999-2015

1068

Product Version 15.1


All Rights Reserved.

print p;
print p.data;
};
};

See Also

pack() on page 1059

%{... , ...} on page 115

swap() on page 1069

do_pack() on page 1071

do_unpack() on page 1075

20.4.3

swap()

Purpose
Swap small bit chunks within larger chunks

Category
Pseudo-method

Syntax
list-of-bit.swap(small: int, large: int): list of bit
Syntax Example
s2 = s1.swap(2, 4);

Parameters
small

An integer that is a factor of large.

large

An integer that is either UNDEF or a factor of the number of bits in the entire list. If
UNDEF, the method reverses the order of small chunks within the entire list. Thus,
lob.swap(1, UNDEF) is the same as lob.reverse().

Specman e Language Reference


1999-2015

1069
.

Product Version 15.1


All Rights Reserved.

Description
This predefined list method accepts a list of bits, changes the order of the bits, and then returns the
reordered list of bits. This method is often used in conjunction with pack() or unpack() to reorder the
bits in a bit stream going to or coming from the DUT.

Notes

If large is not a factor of the number of bits in the entire list, an error message results.
If small is not a factor of large, you will see an error message. The only exception is if large is UNDEF
and small is not a factor, no swap is performed and no error is issued.

Example 1
This example shows two swaps. The first swap reverses the order of nibbles in every byte. The second
swap reverses the whole list.
my_list
0

1 0

1 0

0 0

1 0 1

0 1

1 0

1 1 1

1 1

0 1 0

1 0

my_list.swap(4, 8)
0

0 0

0 0

0 1

my_list.swap(1, UNDEF)
1

0 1 1

1 1

Example 2
This example shows swap() used with unpack() to reorder the bits before unpacking them.
extend sys {
post_generate() is also {
var num1 : uint (bits : 32);
var num2 : uint (bits : 32);
num1 = 0x12345678;

Specman e Language Reference


1999-2015

1070

Product Version 15.1


All Rights Reserved.

unpack(NULL, pack(NULL, num1).swap(16, -1), num2);


print num2;
unpack(NULL, pack(NULL, num1).swap(8, -1), num2);
print num2;
};
};

Results
num2 = 0x56781234
num2 = 0x78563412

See Also

pack() on page 1059

unpack() on page 1064

%{... , ...} on page 115

do_pack() on page 1071

do_unpack() on page 1075

20.4.4

do_pack()

Purpose
Pack the physical fields of the struct

Category
Predefined method of any struct

Syntax
do_pack(options:pack options, l: *list of bit)
Syntax Example
do_pack(options:pack_options, l: *list of bit) is only {
var L : list of bit = pack(packing.low, operand2,
operand1,operand3);
l.add(L);
};

Specman e Language Reference


1999-2015

1071
.

Product Version 15.1


All Rights Reserved.

Parameters
options

This parameter is an instance of the pack options struct. See Using the Predefined
pack_options Instances on page 1044 for information on this struct.

An empty list of bits that is extended as necessary to hold the data from the struct fields.

Description
The do_pack() method of a struct is called automatically whenever the struct is packed. This method
appends data from the physical fields (the fields marked with %) of the struct into a list of bits according
to flags determined by the pack options parameter. The virtual fields of the struct are skipped.
For example, the following assignment to lob
lob = pack(packing.high, i_struct, p_struct);

makes the following calls to the do_pack method of each struct, where tmp is an empty list of bits:
i_struct.do_pack(packing.high, *tmp)
p_struct.do_pack(packing.high, *tmp)

You can extend the do_pack() method for a struct in order to create a unique packing scenario for that
struct. You should handle variations in packing that apply to many structs by creating a custom
pack_options instance. See Customizing Pack Options on page 1050 for information on how to do
this.

Notes

Do not call the do_pack() method of any struct directly, for example my_struct.do_pack(). Instead
use pack(), for example pack(packing.high, my_struct).
Do not call pack(me) in the do_pack() method. This causes infinite recursion. Call
packing.pack_struct(me) instead. You can call pack() within the do_pack() method to pack objects
other than me.
Do not forget to append the results of any pack operation within do_pack() to the empty list of bits
referenced in the do_pack() parameter list.
If you modify the do_pack() method and then later add physical fields in an extension to the struct,
you may have to make adjustments in the modifications to do_pack().

Example 1
This example shows how to override the do_pack() method for a struct called cell. The extension to
do_pack() overrides any packing option passed in and always uses packing.low. It packs operand2
first, then operand1 and operand3.
Specman e Language Reference
1999-2015

1072

Product Version 15.1


All Rights Reserved.

<'
struct cell {
%operand1: uint(bytes:2);
%operand2: uint(bytes:2);
%operand3: uint(bytes:2);
};
extend cell {
do_pack(options:pack_options, l: *list of bit) is only {
var L : list of bit = pack(packing.low, operand2,
operand1,operand3);
l.add(L);
};
};

Result
Specman pack33> print sys.pi using bin
sys.pi = cell-@0: cell
---------------------------------------------- @pack33
0
%operand1:
0b0010001000111001
1
%operand2:
0b0001101001110101
2
%operand3:
0b0001001010110010
Specman pack33> var L : list of bit = pack(packing.high, sys.pi)
Specman pack33> print L using bin
L = (48 items, bin):
0 0 1 1 1 0 0 1 0 0 0 1 1 0 1 0 0 1 1 1 0 1 0 1
.0
0 0 0 1 0 0 1 0 1 0 1 1 0 0 1 0 0 0 1 0 0 0 1 0
.24

Example 2
In the following example, the do_pack() method for cell is overwritten to use the low_big_endian
packing option by default.
struct cell {
%operand1: uint(bytes: 2);
%operand2: uint(bytes: 2);
%operand3: uint(bytes: 2);
};
extend cell {
do_pack(options: pack_options, l: *list of bit) is only {
if (options == packing.global_default) then {
packing.pack_struct(me,
packing.low_big_endian,l);
} else {
packing.pack_struct(me, options, l);
Specman e Language Reference
1999-2015

1073
.

Product Version 15.1


All Rights Reserved.

};
};
};
extend sys {
pi: cell;
};

Result
Specman pack34> print sys.pi using bin
sys.pi = cell-@0: cell
---------------------------------------------- @pack34
0
%operand1:
0b1111101100100110
1
%operand2:
0b0111011001110000
2
%operand3:
0b1111000110111011
Specman pack34> var M : list of bit = pack(NULL, sys.pi)
Specman pack34> print M using bin
M = (48 items, bin):
0 1 1 1 0 1 1 0 0 0 1 0 0 1 1 0 1 1 1 1 1 0 1 1
1 0 1 1 1 0 1 1 1 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0

.0
.24

Example 3
This example swaps every pair of bits within each 4-bit chunk after packing with the packing options
specified in the pack() call.
struct cell {
%operand1: uint(bytes: 2);
%operand2: uint(bytes: 2);
%operand3: uint(bytes: 2);
};
extend cell {
do_pack(options:pack_options, l: *list of bit) is only {
var L1 : list of bit;
packing.pack_struct(me, options, L1);
var L2 : list of bit = L1.swap(2,4);
l.add(L2);
};
};

Result
Specman pack35> print sys.pi using bin
sys.pi = cell-@0: cell
---------------------------------------------- @pack35
Specman e Language Reference
1999-2015

1074

Product Version 15.1


All Rights Reserved.

0
%operand1:
0b0010001000111001
1
%operand2:
0b0001101001110101
2
%operand3:
0b0001001010110010
Specman pack35> var M : list of bit = pack(NULL, sys.pi)
Specman pack35> print M using bin
M = (48 items, bin):
1 1 0 1 0 1 0 1 1 0 0 0 1 0 0 0 1 1 0 0 0 1 1 0
0 1 0 0 1 0 0 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 0

.0
.24

See Also

pack() on page 1059

unpack() on page 1064

%{... , ...} on page 115

swap() on page 1069

do_unpack() on page 1075

20.4.5

do_unpack()

Purpose
Unpack a packed list of bit into a struct

Category
Predefined method of any struct

Syntax
do_unpack(options:pack options, l: list of bit, begin: int): int
Syntax Example
do_unpack(options:pack_options, l: list of bit, begin: int):int is only {
var L : list of bit = l[begin..];
unpack(packing.low, L, op2, op1, op3);
return begin + 8 + 5 + 3;
};

Specman e Language Reference


1999-2015

1075
.

Product Version 15.1


All Rights Reserved.

Parameters
options

This parameter is an instance of the pack options struct. See Using the Predefined
pack_options Instances on page 1044 for information on this struct.

A list of bits containing data to be stored in the struct fields.

from

An integer that specifies the index of the bit to start unpacking.

int (return value)

An integer that specifies the index of the last bit in the list of bits that was unpacked.

Description
The do_unpack() method is called automatically whenever data is unpacked into the current struct. This
method unpacks bits from a list of bits into the physical fields of the struct. It starts at the bit with the
specified index, unpacks in the order defined by the pack options, and fills the current structs physical
fields in the order they are defined.
For example, the following call to unpack()
unpack(packing.low, lob, c1, c2);

makes the following calls to the do_unpack method of each struct:


c1.do_unpack(packing.low, lob, index);
c2.do_unpack(packing.low, lob, index);

The method returns an integer, which is the index of the last bit unpacked into the list of bits.
The method issues a runtime error message if the struct has no physical fields. If at the end of packing
there are leftover bits, it is not an error. If more bits are needed than currently exist in the list of bits, a
runtime error is issued (Ran out of bits while trying to unpack into struct_name).
You can extend the do_unpack() method for a struct in order to create a unique unpacking scenario for
that struct. You should handle variations in unpacking that apply to many structs by creating a custom
pack_options instance. See Customizing Pack Options on page 1050 for information on how to do
this.

Notes

Do not call the do_unpack() method of any struct directly, for example my_struct.do_unpack().
Instead use unpack(), for example unpack(packing.high, lob, my_struct).

Specman e Language Reference


1999-2015

1076

Product Version 15.1


All Rights Reserved.

When you modify the do_unpack() method, you need to calculate and return the index of the last
bit in the list of bits that was unpacked. In most cases, you simply add the bit width of each physical
field in the struct to the starting index parameter. If you are unpacking into a struct that has conditional
physical fields (physical fields defined under a when, extend, or like construct), this calculation is
a bit tricky. See the Verification Advisors patterns on packing for an example of how to do this.

Example 1
This first example shows how to modify do_unpack() to change the order in which the fields of a struct
are filled. In this case, the order is changed from op1, op2, op3 to op2, op1, op3. You can
see also that do_unpack() returns the bit widths of the three physical fields, op1, op2, and op3, to
the starting index, begin.
struct cell {
%op1: uint(bytes:1);
%op2: uint(bits:5);
%op3: uint(bits:3);
};
extend cell {
do_unpack(options:pack_options, l: list of bit,
begin: int) :int is only {
var L : list of bit = l[begin..];
unpack(packing.low, L, op2, op1, op3);
return begin + 8 + 5 + 3;
};
};

Result
Specman pack36> var P : list of bit
{0;0;0;0;1;1;0;1;1;1;0;0;0;0;1;0;};
Specman pack36> unpack(NULL, P, sys.pi)
Specman pack36> print sys.pi using bin
sys.pi = cell-@0: cell
---------------------------------------------- @pack36
0
%op1:
0b00011101
1
%op2:
0b10000
2
%op3:
0b010

Example 2
This example modifies the do_unpack method of the frame struct to first calculate the length of the
data field. The calculation uses begin, which indicates the last bit to be unpacked, to calculate the
length of data.

Specman e Language Reference


1999-2015

1077
.

Product Version 15.1


All Rights Reserved.

extend sys {
!packet1 : packet;
!packet2 : packet;
post_generate() is also {
var raw_data : list of byte;
for i from 0 to 39 {
raw_data.add(i);
};
unpack(packing.low, raw_data, packet1);
print packet1.header, packet1.frame.data,
packet1.frame.crc;
unpack(packing.high, raw_data, packet2);
print packet2.header, packet2.frame.data,
packet2.frame.crc;
};
};
struct packet {
%header
: int (bits : 16);
%frame
: frame;
};
struct frame {
%data[len] : list of byte;
%crc
: int (bits : 32);
len : int;
do_unpack(options :pack_options, l :list of bit,
begin :int):int is first {
if options.reverse_fields then {
len = (begin - 32 + 1) / 8;
} else {
len = (l.size() - begin - 32) / 8;
};
};
};

Results
packet1.header = 256
packet1.frame.data =
13 12 11
25 24 23
35 34

Specman e Language Reference


1999-2015

(34 items, dec):


10
9
8
7
6
5
4
22
21
20 19 18 17 16
33
32
31 30 29 28 27

1078

2
15
26

14

.0
.12
.24

Product Version 15.1


All Rights Reserved.

packet1.frame.crc = 656811300
packet2.header = 10022
packet2.frame.data = (34 items, dec):
26 27 28 29
30
31 32
14 15 16 17
18
19 20
4
5
6
7
8
9

33
21
10

34
22
11

35
23
12

36
24
13

37
25

.0
.12
.24

packet2.frame.crc = 50462976

See Also

pack() on page 1059

unpack() on page 1064

%{... , ...} on page 115

swap() on page 1069

do_pack() on page 1071

Specman e Language Reference


1999-2015

1079
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

1080

Product Version 15.1


All Rights Reserved.

21

Macros

This chapter describes how to extend the e language by defining macros:

Overview of e Macros on page 1081

define as on page 1085

define as computed Macro on page 1096

Match Expressions in e Macros on page 1109

Tracing Macro Expansion on page 1117

Macro Error Messages on page 1118

Debugging Macros on page 1120

21.1 Overview of e Macros


You can extend e by adding new language constructs for any of the following syntactic categories:

Statements

Struct members

Actions

Expressions

Coverage group items

Types

Commands

You can add a new construct by defining a macro. In general, a macro definition specifies:

A syntactic pattern that defines a new syntactic construct in the language

A replacement that specifies e code containing other, already existing constructs of the same category.

Specman e Language Reference


1999-2015

1081
.

Product Version 15.1


All Rights Reserved.

For example, you can create a new kind of action to determine which of two numeric expressions has the
larger value. The first expression is an assignable expression such as a variable. The action then assigns
the maximum value to the first expression. This new language construct has the following syntax:
largest lhs-exp exp

The result of this action is that the value of lhs-exp becomes the largest of the value of lhs-exp and the
value of exp. If the value of variable x is 5, then using the new construct as follows:
largest x 4

does not change anything, but the following:


largest x 7

changes the value of x to 7.


This kind of action can be added by defining the following macro:
define <largestaction> "largest <leftexp> <rightexp>" as {
if <rightexp> > <leftexp> then {
<leftexp> = <rightexp>;
};
};

This define statement consists of:

The macro name <largestaction> indicates that the new language construct belongs to the
action syntactic category.
The match expression largest <leftexp> <rightexp> specifies that the new construct consists
of the keyword largest followed by two expressions separated by white space.
The replacement {if ...then ...} specifies that each time a construct matching the match expression
is found in e code, it is replaced by the specified if...then action.

Match expressions in macro definitions specify the syntactic pattern of the new construct. They contain
elements such as:

Literal characters
In the example above, largest and the spaces separating the two expressions are literal characters.

Syntactic arguments in the form


<[tag]syntactic-type>
where tag is an e name. In the example above, <leftexp> and <rightexp> are syntactic arguments.

Regular expression operators such as options and alternatives

Specman e Language Reference


1999-2015

1082

Product Version 15.1


All Rights Reserved.

The syntactic types allowed in match expressions include the five syntactic categories and some other
syntactic types:
<statement>
<struct_member>
<action>
<exp>
<command>
<name>
<file>
<num>
<block>
<type>
<cover_item>
<any>

For a description of these syntactic types, see Table 21-3 on page 1111. All the possible elements of a
match expression are described in detail in Match Expressions in e Macros on page 1109.
The following considerations apply to the replacement code of define as and define as computed
macros:

The replacement code of a <statement> macro must not contain #define, #undef, import, verilog
import, or package statements; these listed statements can only appear directly in the code.
For macros of the <exp> and <type> syntactic categories, the replacement code must contain exactly
one construct of the same category.
If a macro of the <exp> syntactic category needs to contain actions, one solution is the construct
evaluate { ... } on page 133.
For macros of the <action>, <struct_member>, <statement>, <cover_item>, and
<command> syntactic categories, the replacement code can contain multiple constructs separated by
a semicolon. The replacement code can also be empty.
For <action> macros, if there are several semicolon-separated actions in the replacement code, and
some of them are var actions, the scope of these variables is inside the replacement, and they are not
seen outside the macro. However, if there is only one action, and it is a var action, the variable defined
by it has outer scope and can be used after the macro call.
For <command> macros, if there are multiple semicolon-separated items in the replacement code, it
is considered a block of actions. It is impossible to define several non-action commands in one macro.
The scoping rules for <action> macros also applies to <command> macros.

Once a macro is defined, the construct it introduces becomes a legal e construct. Each occurrence of
such a construct later in the code is replaced by other constructs, as specified by the macro. The macro
can be used in the replacement code of other macros.

Specman e Language Reference


1999-2015

1083
.

Product Version 15.1


All Rights Reserved.

Any new macro you define takes priority over all previously defined macros for the same category. The
definition order is determined by the order of macro definitions within a module and the order in which
modules are loaded. This means that if some e code matches more than one macro of the specified
category and can be treated as more than one language construct of that category, the most recent macro
definition is used. In particular, all user-defined constructs have priority over all built-in constructs.
There are two kinds of macros in e:

define as macros

define as computed macros

Both kinds of macros add a new construct to the language by defining the e code that replaces
occurrences of the match expression later in the program. But they are different in how they define the
replacement. In define as macros, the replacement is given as template code. In define as computed
macros, the replacement code is calculated as a string in a procedural way, just as in a regular routine.
For example, the <largestaction> macro can be modified to calculate either maximum or minimum.
However, this cannot be done using define as, because the replacement code for calculating the
minimum is different from the code for calculating the maximum. The replacement code cannot just be
given as a template. The macro must return the appropriate code depending on which keyword, largest
or smallest, is used. This macro can be defined using define as computed:
define <largest_smallestaction>
"(largest|smallest) <leftexp> <rightexp>" as computed {
var cmp: string = (<1> == "largest") ? ">" : "<";
return append("if ", <rightexp>, cmp, <leftexp>, "then {",
<leftexp>, "=", <rightexp>, "}");
};

define as computed macros give maximum flexibility in generating the replacement. However, they are
more complicated and typically they are less readable.
Another difference is that constructs defined by define as macros can be used in the same module in
which the macro is defined, after the macro definition itself, but constructs defined by define as
computed macros become available only after the whole module is loaded, and cannot be used in the
same module.
It is better to use define as for every construct that can be implemented with a simple syntactic template.
Use define as computed only when there is no other choice.
Sometimes the expanded macro code needs to contain or depends on source information. For example,
a macro might need to print the source module name and line number, or it might need to create different
code, depending on the module in which the macro is used.
For define as macros, you can access the source information in the expanded macro code by using the
following built-in replacement terms:

Specman e Language Reference


1999-2015

1084

Product Version 15.1


All Rights Reserved.

<current_line_num> is replaced in the expanded macro code by the current source line number.
<current_module_name> is replaced in the expanded macro code by the current source module
name.

For define as computed macros, you can call the following built-in routines within the macro
definition:

get_current_line_num() returns the source line number in which the macro is called.
get_current_module() returns the reflection representation of the module in which the macro is
called.

See Also

Syntactic Elements on page 42

Match Expressions in e Macros on page 1109

define as on page 1085

define as computed Macro on page 1096

Tracing Macro Expansion on page 1117

21.2 define as
Purpose
Define a new language construct using template replacement code

Category
Statement

Syntax
define <tag'syntactic-category> match-expression as { replacement }
Syntax Example
<
define <largestaction> "largest <exp> <num>" as {
if <num> > <exp> then {<exp> = <num>};
};
>

Specman e Language Reference


1999-2015

1085
.

Product Version 15.1


All Rights Reserved.

Parameters
tag'syntactic-category

The tag is any legal e name. It must start with a letter and consist of
letters, digits and underscores (_). See Legal e Names on page 41
for more information.
The syntactic-category indicates the syntactic category of the macro
and is one of the following keywords:

statementA top-level declarative construct.

struct_memberA part of a struct definition.

actionA procedural construct that can be executed.

expA construct that can be evaluated (an expression).

typeA type name

cover_itemA coverage group item

commandA construct that can be entered at Specman command


prompt and in ecom files.

The tag and syntactic category in combination must form a unique


name for the macro within the package. For example, it is possible to
have both a <do_itstatement> and a <do_itaction>, but there cannot
be two <do_itaction> macros in the same package. However, it is
possible to have macros with the same name in different packages, just
as different types in different packages can have the same name.
match-expression

A quoted string containing the syntactic pattern that specifies what


constructs are matched by the macro. A match expression is a
sequence of literal characters and syntactic arguments, possibly with
regular expression operators such as options and alternatives. Once
the macro is defined, you can use the syntax specified by the match
expression wherever it is legal to use a construct of the same syntactic
category as the macro.
Match expression syntax and meaning are described in detail in
Match Expressions in e Macros on page 1109. For a list of syntactic
arguments allowed in match expressions, see Table 21-3 on page 1111.

Specman e Language Reference


1999-2015

1086

Product Version 15.1


All Rights Reserved.

replacement

Template e code, usually containing replacement terms that refer to


the elements of the match expression. This code must constitute a
legal e construct of the same category, either a built-in construct or a
construct defined by another macro.
When the macro is used, each replacement term is substituted by the
text matched by the corresponding element of the match expression.
The kinds of replacement terms that can be used in the replacement
code, and their corresponding match-expression elements, are shown
in Table 21-1.
The treatment of multiple semicolon-separated items in replacement
code is described in Overview of e Macros on page 1081.

Table 21-1

Replacement Term Syntax for define as

Replacement Term
Kind
Syntactic argument name

Description

Examples

The name of a syntactic argument (with or


without repetition) in the match expression. It
refers to the text in the match expression that is
matched by the syntactic argument. See
Syntactic Argument Names on page 1112 for
more information.

<action>
<firstexp>

Note If you need to refer the separate


elements of a repetition argument, you must use
define as computed Macro on page 1096.

Specman e Language Reference


1999-2015

1087
.

Product Version 15.1


All Rights Reserved.

Table 21-1

Replacement Term Syntax for define as

Replacement Term
Kind
Submatch number

Description

Examples

A numeric constant enclosed in triangular


brackets that refers to the text matched by a
grouping, option or syntactic argument within
the match expression. For example in the
following match expression, <1> represents the
entire grouping (including the <exp> and the
optional Hello), <2> represents the <exp>,
and <3> represents the optional Hello:

<1>
<2>

"My (<exp>[Hello])"

If the number is not positive, or if it exceeds the


number of submatches in the match expression,
a compile time error is issued.
See Submatches on page 1115 for more
information.
Submatch label

The submatch label of a grouping or an option


in the match expression. It refers to the text
matched by that grouping or option. See
Submatch Labels on page 1113 for more
information.

<OPT>
<EXP>

Replacement term with a


default value

You can give any of the replacement terms


(syntactic argument name, submatch number,
submatch label) a default value. The default
value appears within the same triangular
brackets and is separated from the replacements
term by a bar |. The default value is any text
that is substituted when the corresponding
element does not appear in the input.

<num|0>
<2|x>

<?>

An alphanumeric character sequence that is


unique over all expansions of this macro. This
is useful for creating unique names that do not
collide in the various places this macro is used.

var a<?>: int;

<current_line_num>

Is replaced in the expanded macro code by the


current source line number

See Example 10

Specman e Language Reference


1999-2015

1088

on page 1095

Product Version 15.1


All Rights Reserved.

Table 21-1

Replacement Term Syntax for define as

Replacement Term
Kind
<current_module_name>

Description

Examples

Is replaced in the expanded macro code by the


current source module name

See Example 10
on page 1095

Description
A define as macro creates a new language construct of the specified syntactic category (action,
command, and so on).
You give the macro name by assigning it a tag and a syntactic category. The replacement specifies what
is to be done each time such a construct occurs in the program or is executed at the Specman prompt.
When Specman expects a construct of that category and finds a construct that matches the match
expression of the macro, Specman replaces that construct with the replacement code, substituting
replacement terms with the corresponding submatches. This process can be recursive. If the new
construct also matches the match expression of some macro, its replacement is used in turn.
Any new macro you define with define as or define as computed takes priority over all previously
defined macros for the same category. The order of definition is determined by the order of their
definition within a module and by the order in which modules are loaded.

Example 1

Define a New Expression Kind

This example defines a new kind of expression that finds the maximum between three given numeric
expressions.
<
define <max3exp> "max3 <firstexp>,<secondexp>,<thirdexp>" as {
max(<firstexp>, max(<secondexp>, <thirdexp>))
};
>

Once this macro is loaded, it can be used either from the Specman command prompt or in the code. For
example:
cmd-prompt> print (max3 1,2,3)
(max3 1,2,3) = 3
cmd-prompt> print (max3 10,15,5)
(max3 10,15,5) = 15

Specman e Language Reference


1999-2015

1089
.

Product Version 15.1


All Rights Reserved.

Example 2

Define a New Command

This example defines a new Specman command that executes the UNIX ls command with any of its
flags. The new command is invoked by lis with a list of flags.:
<
define <dir_liscommand> "lis[ <any>]" as {
print output_from("ls <any>") using items=UNDEF;
};
>

At the Specman prompt you can enter the following commands to list files in the current directory. The
-lt flags and the *.e syntax are the same as for the UNIX ls command:
cmd-prompt> lis
cmd-prompt> lis -lt *.e

Example 3

Define a New Action

This example defines a new action that generates a frame with specified field values, and calls a method
named send():
<
define <simple_frameaction> "send simple frame \
<dest_addrnum> <source_addrnum> <sizenum>" as {
var f: frame;
gen f keeping {
.kind not in [SRAM,DUT];
.size == <sizenum>;
.dest_address == <dest_addrnum>;
.source_address == <source_addrnum>;
};
f.send();
};
>

Here is an example of using the send simple frame macro:


<
extend sys {
run() is also { send simple frame 0x00fe 0x0010 0xfa };
};
>

Example 4

Define a New Action with Optional Value

This example defines a new action that generates a frame of a specified kind with an optional
dest_address value, and calls the send() method.
Specman e Language Reference
1999-2015

1090

Product Version 15.1


All Rights Reserved.

The <name> argument of the match expression denotes the value of the kind field of the frame, and
the <dest_addrnum> argument denotes the value of the dest_address field. If no dest_address is
given, then the default value 0x1000 is used.
<
define <configure_frameaction>
"<name> config frame[ <dest_addrnum>]" as {
var f: frame;
gen f keeping {
.kind == <name>;
.dest_address == <dest_addrnum|0x1000>;
.size == 64;
};
f.send();
};
>

The <dest_addrnum|0x1000> item in the replacement has a default value. When a dest_addr is given,
then it is used. When it is not given, then default value of 0x1000 is used.
Here is a usage example for this macro:
<
extend sys {
run() is also {
SRAM config frame;
DUT config frame 0x1001;
};
};
>

Example 5

Define a New Kind of Struct Member

This example defines a new kind of struct member, called bean, that adds to a struct a new private
field of a given type, as well as the public getter and setter methods for that field.
<
define <beanstruct_member> "bean <name>[ ]:[ ]<type>" as {
private <name>: <type>;
get_<name> (): <type> is {
return <name>;
};
set_<name> (val: <type>) is {
<name> = val;
};
};
>
Specman e Language Reference
1999-2015

1091
.

Product Version 15.1


All Rights Reserved.

Here is a usage example for this macro:


<
struct bean_struct {
bean x: int;
};
extend sys {
run () is also {
var a: bean_struct = new;
a.set_x(5);
print a.get_x();
};
};
>

The bean x: int struct member declaration in this example adds both the x field of type int to the
struct and two methods get_x() and set_x(). These methods return and modify the value of x,
respectively.

Example 6

Define a Pattern

This example defines a pattern for debugging objects that consists of:

A flag for each instance of a debuggable struct

A list of debuggable structs per type under sys


<
define <debuggable_structstatement>
"debuggable (struct <name>[ like <parentname>]) {<struct_member>;...}" as
{
<1> {
debug_flag: bool;
<struct_members>;
};
extend sys {
debug_monitor_<name>: list of <name>;
};
};
debuggable struct a {
x: int;
};
>

The struct a defined here has a debug_flag field of type bool and an x field of type int. A list of
such structs, called debug_monitor_a, is added to sys.
Specman e Language Reference
1999-2015

1092

Product Version 15.1


All Rights Reserved.

The submatch number <1> used in the replacement refers to the entire submatch in the parentheses:
(struct <name>[ like <parentname>])

A debuggable struct statement can specify a parent to the struct.


The <struct_members> replacement term refers to the whole repetition argument within the curly
brackets.
It is usually recommended to use submatch labels rather than submatch numbers. The above macro can
be rewritten as:
<
define <debuggable_structstatement> "debuggable \
(<HEAD>struct <name>[ like <parentname>]) {<struct_member>;...}" as {
<HEAD> {
debug_flag: bool;
<struct_members>;
};
extend sys {
debug_monitor_<name>: list of <name>;
};
};
>

Example 7

Define a New Expression for Checks

In the following example, the frame struct has a when subtype that adds a Boolean field good_frame
only for frames of kind SRAM. The macro defines a new expression that checks whether a given frame
is of kind SRAM, and whether its good_frame value is TRUE.
<
define <good_frameexp> "<frameexp> is good frame" as {
<frameexp> is a SRAM frame (sram<?>) and sram<?>.good_frame
};

extend sys {
f1: frame;
f2: frame;
run() is also {
f1 = new SRAM frame with { .good_frame = TRUE; };
f2 = new DUT frame;
if (f1 is good frame) or (f2 is good frame) {
out("One of the frames is good!");
};
Specman e Language Reference
1999-2015

1093
.

Product Version 15.1


All Rights Reserved.

};
};
>

The <?> element attaches a prefix to the sram that is unique for every usage of the macro. Without
<?>, the code does not compile. Because there are two uses of the macro within the expression (f1 is
good frame) or (f2 is good frame), without <?> the macro generates a variable named sram twice in
the scope of the same expression.
To see how sram<?> is expanded when the macro is used, enter the trace reparse command before
the example file is loaded. The following is a printout of the results. For each call to the macro, the <?>
element is replaced by a unique string.
D> <good_frameexp> f1 is good frame
D> reparsed as: f1 is a SRAM frame (sram__frame_0__) and
sram__frame_0__.good_frame
D> <good_frameexp> f2 is good frame
D> reparsed as: f2 is a SRAM frame (sram__frame_1__) and
sram__frame_1__.good_frame

Example 8

Define a New Template Type

In the following example, a template type called hash_map has two type parameters for key and value.
You want to use several different template instances of hash_map but, although all of them use string as
the key type, they use different bit-size variants of uint as the value type.
The following macro avoids the need to repeatedly write long type names such as hash_map of (string,
uint(bits: 16)).
define <string_uint_map'type> "my_hash_map\(<num>\)" as {
hash_map of (string, uint(bits: <num>))
};

There are several ways you can use this macro:


-- Define a variable of type "hash_map of (string, uint(bits: 16))"
var map_list: my_hash_map(16);
-- Extend a "when" subtype of "hash_map of (string, uint(bits: 16))"
extend good my_hash_map(64) { ... }

Example 9

Define a New Coverage Item Macro

The following example defines a new macro of the <cover_item> syntactic category. This macro lets
you encapsulate the definition of two coverage items and a cross between them.
define <cross_two_items'cover_item>
Specman e Language Reference
1999-2015

1094

Product Version 15.1


All Rights Reserved.

"cross_items <first'name>[],[]<second'name>" as {
item <first'name>;
item <second'name;
cross <first'name>, <second'name>;
};

You can use this macro in your code as follows:


struct packet {
event e;
size: int;
color: color_t;
cover e is {
cross_items size, color;
};
};

Example 10

Including Source Information in a define as Macro

The following macro, modify_and_print, modifies the left hand side of an expression and prints a
message showing the line number and module in which the change occurred:
<'
define <my'action> "modify_and_print <field'exp> <value'exp>" as {
<field'exp> = <value'exp>;
out("*** The value of <field'exp> was changed to ", <value'exp>,
" at line <current_line_num> in @<current_module_name>");
};
'>

Suppose you call this macro from within the following module, called my_module:
<'
extend sys {
x : int;
run() is also {
modify_and_print x 10;
};
};
'>

When you run the test, the macro assigns the value 10 to the field x and prints the following message:
*** The value of x was changed to 10 at line 5 in @my_module

See Also

Overview of e Macros on page 1081

Specman e Language Reference


1999-2015

1095
.

Product Version 15.1


All Rights Reserved.

Match Expressions in e Macros on page 1109

define as computed Macro on page 1096

Tracing Macro Expansion on page 1117

21.3 define as computed Macro


The defined as computed macro is described in the following sections:

define as computed on page 1096

Using the reject_match() Routine on page 1101

define as computed Examples on page 1105

21.3.1

define as computed

Purpose
Define a new language construct using an action block to build the replacement code

Category
Statement

Syntax
define < tagsyntactic-category> match-expression as computed {action; }
Syntax Example
<
define <time_commandaction> "time[ <any>]" as computed {
if <any> == "on" {
return( "tprint = TRUE; print sys.time;" );
} else if <any> == "off" {
return("tprint = FALSE");
} else {
error("Usage: time [on|off]");
};
};
>

Specman e Language Reference


1999-2015

1096

Product Version 15.1


All Rights Reserved.

Parameters
tag'syntactic-category

The tag is any legal e name. It must start with a letter and consist of letters,
digits and underscores (_). See Legal e Names on page 41 for more
information.
The syntactic-category indicates the syntactic category of the macro and is
one of the following keywords:

statementA top-level declarative construct.

struct_memberA part of a struct definition.

actionA procedural construct that can be executed.

expA construct that can be evaluated (an expression).

typeA type name

cover_itemA coverage group item

commandA construct that can be entered at Specman command prompt


and in ecom files.

The tag and syntactic category in combination must form a unique name for
the macro within the package. For example, it is possible to have both a
<do_itstatement> and a <do_itaction>, but there cannot be two
<do_itaction> macros in the same package. However, it is possible to have
macros with the same name in different packages, just as different types in
different packages can have the same name.
match-expression

A quoted string containing the syntactic pattern that specifies what constructs
are matched by this macro. A match expression is a sequence of literal
characters and syntactic arguments, possibly with regular expression
operators such as options and alternatives.
Once the macro is defined, you can use the syntax specified by the match
expression wherever it is legal to use a construct of the same syntactic
category as the macro.
Match expression syntax and meaning are described in detail in Match
Expressions in e Macros on page 1109. For a list of syntactic arguments
allowed in match expressions, see Table 21-3 on page 1111.

Specman e Language Reference


1999-2015

1097
.

Product Version 15.1


All Rights Reserved.

action;...

A block of actions that are executed when the match expression is matched.
This action block is treated as the body of a method that returns a string, so
you must use the result variable or the return action to return a result from
the action block. The resulting string must contain a legal e construct of the
same category, either built-in or defined by another macro. This construct is
used as the replacement code.
The action block can contain replacement terms that refer to elements of the
match expression.
When the macro is used, each replacement term is substituted by the text
matched by the corresponding match-expression element. Most replacement
terms in the action block are expressions of type string.
The kinds of replacement terms that can be used in the action block, and their
corresponding match-expression elements, are shown in Table 21-2 on page
1098.
The treatment of multiple semicolon-separated items in replacement code is
described in Overview of e Macros on page 1081.
To apply restrictions on the syntax specified by the match expression, you can
use the reject_match() predefined routine to treat a match as illegal. See
Using the reject_match() Routine on page 1101.

Table 21-2

Replacement Term Syntax for define as computed

Replacement
Term Kind
Syntactic
argument name

Description

Examples

The name of a syntactic argument without repetition in the


match expression. It refers to the text in the match
expression that is matched by the syntactic argument. See
Syntactic Argument Names on page 1112 for more
information.

<action>
<firstexp>

Specman e Language Reference


1999-2015

1098

Product Version 15.1


All Rights Reserved.

Table 21-2

Replacement Term Syntax for define as computed, continued

Replacement
Term Kind
Repetition
syntactic
argument name

Description

Examples

The name of a repetition syntactic argument in the match


expression. Unlike other replacement terms, it is an
expression of type list of string, where each element of the
list represents the string matched by a separate element of
the repetition.

<exps>
<myactions>

If you need to refer to the entire string matched by the whole


repetition, use a submatch number or submatch label. To use
a submatch label, the entire repetition argument must be
enclosed in parentheses in the match expression.
See Syntactic Argument Names on page 1112 and
Submatch Labels on page 1113 for more information.
Submatch
number

A numeric constant enclosed in triangular brackets that


refers to the text matched by a grouping, option or syntactic
argument within the match expression. For example in the
following match expression, <1> represents the entire
grouping (including the <exp> and the optional Hello),
<2> represents the <exp>, and <3> represents the optional
Hello:

<1>
<2>

"My (<exp>[Hello])"

Notes

For repetition arguments, the submatch number refers to


the entire string. To refer to the list of strings of a
repetition argument, use the repetition syntactic
argument name.
If the number is not positive, or if it exceeds the number
of submatches in the match expression, a compile time
error is issued.

See Submatches on page 1115 for more information.


Submatch label

The submatch label of a grouping or an option in the match


expression. It refers to the text matched by that grouping or
option. See Submatch Labels on page 1113 for more
information.

Specman e Language Reference


1999-2015

1099
.

<OPT>
<EXP>

Product Version 15.1


All Rights Reserved.

Table 21-2

Replacement Term Syntax for define as computed, continued

Replacement
Term Kind
<?>

Description

Examples

An alphanumeric character sequence that is unique over all


expansions of this macro. This is useful for creating unique
names that do not collide in the various places this macro is
used.

return append(
"var x<?>: ",
<type>);

Unlike other replacement terms, you must insert this term


into the returned string expression. It is not itself recognized
as a legal string expression in define as computed. The
following example illustrates an illegal use of <?> in define
as computed:
-- illegal in define as computed
return append("var x", <?>, ": ", <type>);

Description
A define as computed statement creates a new language construct of a given category (action,
command, and so on).
You give the macro name by assigning it a tag and a syntactic category. The action block specifies what
is to be done each time such a construct occurs in the program or is executed at the Specman prompt.
When Specman expects a construct of that category and finds a construct that matches the match
expression of the macro, Specman executes the action block of the macro, substituting any replacement
terms with the corresponding submatches. Then, the string returned by the action block is treated as the
code to be executed. This process can be recursive. If the new code also matches the match expression
of some macro, its replacement is used in turn.
Any new macro you define with define as or define as computed takes priority over all previously
defined macros for the same category. The order of definition is determined by the order of their
definition within a module and by the order in which modules are loaded.
For simple replacements, it is recommended that you use the define as statement rather than define as
computed. define as computed macros are more complicated, less readable, and less easy to debug.
Use them only when there is no other choice.

Specman e Language Reference


1999-2015

1100

Product Version 15.1


All Rights Reserved.

When compiling a file that uses a construct defined by a define as computed macro, you have two
choices:

By default, you must use two-phase compilation. Compile the file that defines the macro first. Then
you can use the compiled e-library or executable to load or compile any file that uses this newly
defined construct.
Optionally, you can use the sn_compile.sh -enable_DAC option to perform single-phase compilation
of define as computed macros.

However, if you have the following in the same compilation cluster, single-phase compilation causes an
error to be issued.

A C routine declaration

An extension of init() of an instantiated struct which calls the C routine

Computed macro definitions (but not necessarily their use), unless they occur in the top module

Notes

Language constructs defined by define as computed macros cannot be used in the same file they
are defined in. To use a such a construct in a loaded file, you must also load the file that contains the
define as computed statement.
You can debug define as computed macros after you set the macro debugging mode to expansion.
cmd-prompt> config debug -macro_debug_mode=expansion

21.3.2

Using the reject_match() Routine

Within a define as computed macro, you can use the reject_match() routine to apply further
restrictions on the syntax specified by the match expression. This feature is useful when a match
expression (Match Expressions in e Macros on page 1109) cannot express the exact syntax, or when
such a match expression will be less convenient or too complicated.
Notes about using this routine:

The reject_match() routine can only be used in the context of a define as computed macro. Any
other usage causes a run-time error.
Use this routine only when the reason for the macro not to match is purely syntactic. If the code
matched with the macro is erroneous for another reason, for example, use the error() routine to report
an error message, as shown in Example 1 on page 1105.

The following are several examples of using this routine.

Specman e Language Reference


1999-2015

1101
.

Product Version 15.1


All Rights Reserved.

Example 1
The string returned by the action block is treated as code to be executed. If this new code also matches
the match expression of the macro, the macro replacement code is matched again and again by the same
macro, resulting in infinite recursion.
The following example creates a version of the str_len() routine that gets multiple string parameters and
calculates their total length. The reject_match() routine rejects any match that has only one string
parameter, which prevents recursion:
define <multi_str_len'exp> "str_len[]\(<exp>,...\)" as computed {
if (<exps>.size()) == 1 then {
reject_match();
};
return append("str_len(append(", str_join(<exps>, ","), "))");
};

In this case, it is impossible to express the exact syntax with just a match expression. The match must
have at least two expressions within parentheses, which cannot be done without reject_match().

Example 2
For example, you can create a macro that will let you define several struct fields of the same type in one
definition. The reject_match() routine enforces the condition that the match code must have a
comma-separated list of at least two names, which will prevent an infinite recursion.
define <multi_field'struct_member> "<name>,...[]:[]<type>" as computed {
if (<names>.size()) == 1 then {
reject_match();
};
for each (name) in <names> do {
result = append(result, name, ":", <type>, ";");
};
};

This macro lets you use field definitions such as the following:
struct s {
x, y: int;
};

Example 3
You might want to create the code such as the following, where the second method, size(), will be
similar to the first method, get_size().
struct packet {
private size: int;;
Specman e Language Reference
1999-2015

1102

Product Version 15.1


All Rights Reserved.

get_size() : int is {
return size;
};
size() : int is get_size;
};

Although you can permit method declarations such as this one by using a macro, the new syntax will
override the existing syntax of some method declarations, such as is empty or is undefined. For these
cases, you can use the reject_match() method to define the macro so that it does not match in those
cases:
define <method_alias'struct_member>
"<SIGNATURE><new'name>[]\(\)[[]:[]<ret'type> is <other'name>"
as computed {
if <other'name> == "empty" or <other'name> == "undefined" then {
reject_match();
};
if <ret'type> == NULL then {
return append(<SIGNATURE>, " is { ", <other'name>, "(); }");
} else {
return append(<SIGNATURE>, " is {return ", <other'name>, "(); }");
};
};

The declaration of the size() method in this macro will be expanded as follows:
size(): int is {
return get_size();
};

If reject_match() is not used in this macro, declarations such as the following will be treated
incorrectly:
foo() is empty;

because it will be matched with the macro and wrongly expanded into the following:
foo() is {
empty();
};

21.3.3

Using the get_current_line_num() and


get_current_module() Routines

You can call the following routines from define as computed macros when you want to access source
information:

Specman e Language Reference


1999-2015

1103
.

Product Version 15.1


All Rights Reserved.

get_current_line_num() : int
Returns the source line number in which the macro is called. The routine returns UNDEF if it is
called within a <command> macro, or if it is used from within a command rather than inside a
loaded or compiled module.

get_current_module(): rf_module
Returns the reflection representation of the module in which the macro is called. The routine returns
NULL if it is called within a <command> macro, or if it is used from within a command rather than
inside a loaded or compiled module.

Notes

These routines return an error if called anywhere outside the context of a define as computed macro.
These routines are called during macro expansion, at an early stage of compilation. Therefore, if you
query the rf_module object from within the macro, some information will be missing. For example,
get_type_layers() will return an empty list, even if the module has type declarations or extensions.
This information is available when the rf_module is quereied from outside the macro definition,
after compilation.

In the following example, the special_field macro adds a new field to a struct. The field name is
constructed from the current module name and line number. If the module name has the suffix _xxx, no
field is added.
<'
define <my_field'struct_member> "special_field" as computed {
var m_name: string = get_current_module().get_name();
if m_name !~ "/_xxx$/" then {
result = append("f_", m_name, "_",
get_current_line_num(), ": int");
};
};
'>

When called twice within a module named some_module.e, the special_field macro adds two int fields
to sys, called f_some_module_3 and f_some_module_5:
<'
extend sys {
special_field;
special_field;
};
'>

If the same macro is called from a module named some_module_xxx.e, no fields are added.

Specman e Language Reference


1999-2015

1104

Product Version 15.1


All Rights Reserved.

21.3.4

define as computed Examples

Example 1

Define a New Statement

This example defines a new soft_extend statement, which adds a new item to an existing enumerated
type but is more flexible than the usual extend. When the type already has such item, it does nothing
and does not produce an error message. This might be useful, for example, if you have several different
variants of item sets for the enumerated type in different modules, and these modules can be loaded in
different combinations and in different order.
Note You can use this macro to extend a particular type by a specific item name only once in a single
e module. However, you can use this macro multiple times in a single e module if you specify a unique
item name with each use.
soft_extend1.e
<
define <soft_extendstatement>
"soft_extend <typename> by <itemname>" as computed {
var rfe: rf_enum =
rf_manager.get_type_by_name(<typename>).as_a(rf_enum);
if rfe == NULL {
error("The enum type called does not exist ", <typename>);
};
if not rfe.get_items().has(it.get_name() == <itemname>) {
return appendf("extend %s: [%s]", <typename>, <itemname>);
};
};
>

The first syntactic argument in this macro is the name of an enumerated type; the second is the name of
the item to be added. Using the reflection interface, the macro checks whether such an enumerated type
exists, and if not, issues an error message. Otherwise, again using reflection, the macro checks whether
the enumerated type already has the item to be added (<itemname>). If not, the returned string contains
an extend statement that adds the item. If such an item already exists, the returned string contains a
statement that does nothing.
For more information on the reflection interface, see Chapter 8 Reflection Interface for e in Creating e
Testbenches.

Specman e Language Reference


1999-2015

1105
.

Product Version 15.1


All Rights Reserved.

Example 2

Enhance a Macro to Provide Multiple Items

This example improves the macro from the previous example so that it is possible to provide several
items to soft_extend, similar to the usual extend. The macro checks which items already exist and which
do not, and adds only the new ones.
soft_extend.e
<
define <soft_extendstatement>
"soft_extend <typename>:[ ]\[<itemname>,...\]" as computed {
var rfe: rf_enum =
rf_manager.get_type_by_name(<typename>).as_a(rf_enum);
if rfe == NULL {
error("There is no enum type called ", <typename>);
};
var new_names: list of string =
<itemnames>.all(it not in rfe.get_items().apply(it.get_name()));
return
appendf("extend %s: [%s]", <typename>, str_join(new_names, ","));
};
>

In this macro, the syntactic argument <typename> holds the name of an enumerated type, and a
repetition syntactic argument <itemname>,... holds a list of item names. The name of the repetition,
when used inside the macro body, is in the plural form <itemnames>.
If the enumerated type exists, the macro returns a string containing an extend statement that adds only
those items that do not already exist in the enumerated type.
The following is an example of using this macro. In file color.e, an enumerated type called color is
defined, with three values. In file color1.e, this type is extended to add the values red, green and blue,
without knowing which values are already defined. As a result, the type color has 5 values: black, white,
green, red and blue.
color.e
<
type color: [black, white, green];
>
color1.e
<
import color;
import soft_extend;

Specman e Language Reference


1999-2015

1106

Product Version 15.1


All Rights Reserved.

soft_extend color: [red, green, blue];


>

Example 3

Change a Macro

This example changes the macro configure_frame shown in Example 4 on page 1090, so that if no
dest_address is given, then a generated value is used, rather than a predefined default value.
define as computed is required here because the constraint on the dest_address field must appear only
when dest_address is given, and must not appear otherwise. define as cannot be used here because the
code is not a simple template, but must instead be calculated.
<
define <configure_frameaction>
"<name> config frame[ <dest_addrnum>]" as computed {
var address_constraint: string;
if !str_empty(<dest_addrnum>) then {
address_constraint =
append(".dest_address == ", <dest_addrnum>, ";");
};
return append(" \
var f: frame; \
gen f keeping { \
.kind == ", <name>, "; \
.size == 64;",
address_constraint,
"}; \
f.send(); \
");
};
>

The returned string contains the sequence of actions. The gen action has a constraint for dest_address
only if <dest_addrnum> is non-empty.

Example 4

Define a New Template Type with Variants

The following example enhances Example 8 on page 1094 to enable bit-size variants of both int and
uint as the second template parameter, by using a define-as-computed macro.
define <string_int_map'type> "my_[<SIGNED>signed_]hash_map\(<num>\)"
as computed {
var value_base_type := (<SIGNED> == NULL) ? "uint" : "int";
return append("hash_map of (string, ", value_base_type, "bits: ",
<num>, "))");
Specman e Language Reference
1999-2015

1107
.

Product Version 15.1


All Rights Reserved.

};

There are several ways you can use this macro:


-- Define two fields: one of type "hash_map of (string, uint(bits:20))",
-- and another of type "hash_map of (string, int(bits:32))"
f1: my_hash_map(20);
f2: my_signed_hash_map(32);

Example 5

Expand a Coverage Item

The following example lets you define a coverage item that expands into a sequence of coverage items
on specific bits inside a numeric field.
define <bits'cover_item> "item <name>[ ]\<<from'num>[:<to'num>]\>"
as computed {
var from_bit: int = <from'num>.as_a(int);
var to_bit: int = from_bit;
if <to'num> != NULL then {
to_bit = <to'num>.as_a(int);
};
for i from from_bit to to_bit {
result = appendf("%s item %s_bit_%d: bit = %s[%d:%d];",
result, <name>, i, <name>, i, i);
};
};

The following code uses this macro:


struct packet {
event e;
size: uint;
cover e is {
item size <1>;
item size <4:7>;
};
};

This coverage group code will expand to the following list of coverage items:
item
item
item
item
item

size_bit_1:
size_bit_4:
size_bit_5:
size_bit_6:
size_bit_7:

bit
bit
bit
bit
bit

Specman e Language Reference


1999-2015

=
=
=
=
=

size[1:1];
size[4:4];
size[5:5];
size[6:6];
size[7:7];

1108

Product Version 15.1


All Rights Reserved.

See Also

Overview of e Macros on page 1081

define as on page 1085

Match Expressions in e Macros on page 1109

Tracing Macro Expansion on page 1117

21.4 Match Expressions in e Macros


A match expression is used in a macro definition to specify the syntactic structure of the new language
construct. Elements of the match expressions can be referred to from the macro body. A macro body is
one of the following:

The replacement code of a define as macro

The action block of a define as computed macro

A match expression consists of literal characters and syntactic arguments, possibly with regular
expression operators such as alternative, optional subsequence, and a restricted form of repetition. The
elements of a match expression are defined in the following sections:

Literal Characters on page 1109

Syntactic Arguments on page 1110

Regular Expression Operators in Match Expressions on page 1112

Submatch Labels on page 1113

Special Literal Characters on page 1113

Submatches on page 1115

Problematic Match Expressions on page 1115

Examples on page 1116

21.4.1

Literal Characters

Any ASCII character or sequence of characters that should appear in the new construct is specified
literally in the match expression string.
The following characters have special meaning in the match expression syntax, and they must be
escaped (preceded by a backslash) in order to be taken literally:
( ) [ ] < > | \

If any other character is escaped, the backslash is simply ignored.

Specman e Language Reference


1999-2015

1109
.

Product Version 15.1


All Rights Reserved.

For example, a match expression for the letter x, followed by < and then the letter y, is:
"x\<y"

The meaning of literal characters in a match expression is as follows:

Any character other than white space denotes an appearance of that specific single character in a
matching construct.
Some characters have a special meaning and can be used only in specific situations. For more
information, see Special Literal Characters on page 1113.

The space character in the match expression denotes an appearance of any non-empty number of
subsequent white space characters in a matching construct.
White space characters are spaces, tabs and new lines. Subsequent white space characters in e code
are always collapsed to a single space character (unless they appear inside double quotes). For
convenience, it is allowed to put several subsequent spaces in a match expression. They are treated
as a single space. The other white space characters (\n and \t) cannot appear in a match expression.

21.4.2

Syntactic Arguments

Syntactic arguments are the non-literal elements in a match expression, and they denote something
within a construct that corresponds to a certain syntactic type.

Syntactic Argument Syntax


A syntactic argument has the following form:
<[tag]syntactic-type>
where:

The optional tag is any legal e name. It must start with a letter and consist of letters, digits and
underscores (_).
The syntactic-type is one of the syntactic categories or other types shown in Table 21-3.

The following are examples of syntactic arguments:


<action>
<leftexp>
<paramname>
<any>
Table 21-3 lists the syntactic categories and other syntactic types that can be used as arguments in match
expressions. See Syntactic Elements on page 42 for more information on syntactic categories.

Specman e Language Reference


1999-2015

1110

Product Version 15.1


All Rights Reserved.

Table 21-3

Syntactic Types in Match Expressions

Name

Description

statement

A top level declarative construct.

action

A procedural construct that can be executed.

command

A construct that can be entered at Specman command prompt and


in ecom files.

struct_member

A part of a struct definition.

cover_item

A coverage group item, such as item, cross, or transition

exp

An expressiona construct that can be evaluated.

name

A legal e name. It must start with a letter and consist of letters,


digits and underscores (_).

file

A file name, possibly with a UNIX-style file path.

num

A literal numeric constant.

block

A series of actions, delimited by semicolons and enclosed between


curly braces
Note For defined as computed macros, if you need to access the
individual actions defined in the block, rather than the block as a
whole (especially in a define as computed macro), use
{<action>;...} instead of <block> in the match expression, and
then you can use <actions> in the macro body.

type

A legal e type name, simple or compound

any

Any non-empty sequence of characters

Repetition Syntactic Argument Syntax


A repetition syntactic argument has the following form:
<[tag]syntactic-type>separator...
where:

The optional tag is any legal e name. It must start with a letter and consist of letters, digits and
underscores (_).
The syntactic-type is one of the syntactic categories or other syntactic types shown in Table 21-3.

Specman e Language Reference


1999-2015

1111
.

Product Version 15.1


All Rights Reserved.

The separator is any single literal character except special characters and alphanumerics. For a list
of special characters, see Special Literal Characters on page 1113.

A repetition syntactic argument in a match expression denotes multiple occurrences of a syntactic type,
separated by a specified separator character. For example, the following denotes a sequence of
expressions separated by a comma:
<exp>,...

Note When the repetition appears inside parentheses, square brackets or curly brackets, then an empty
string (repetition with zero elements) is also matched. Otherwise, an empty string is not matched, and
there must be at least one occurrence of the syntactic type.

Syntactic Argument Names


The syntactic argument name is the name you use in the macro body to refer to the syntactic argument.
In case of a regular syntactic argument (without repetition), its name is as it appears in the match
expression. For repetition syntactic arguments, the syntactic type part of the name is written in the plural
form. For example, in the following match expression:
"my <exp> <otherexp> \(<repeatedexp>,...\)"

the names of the three syntactic arguments are:


<exp>
<otherexp>
<repeatedexps> --note the plural form

21.4.3

Regular Expression Operators in Match Expressions

A match expression is a regular expression over literal characters and syntactic arguments, and can
include the following regular expression operators:

GroupingItems enclosed in parentheses


Grouping has no effect on the syntax defined by the macro, but is used for associativity, for
readability, or for referencing a submatch. For example, the following denotes a name, followed by
a colon, a white space, and a type:
(<name>: <type>)

OptionItems enclosed in square brackets.


Enclosing an item or a sequence of items in square brackets denotes an optional occurrence of that
item or sequence. For example, the following denotes an optional occurrence of two expressions
(constructs of the category exp) with two asterisks between them:
[<firstexp>**<secondexp>]

Specman e Language Reference


1999-2015

1112

Product Version 15.1


All Rights Reserved.

AlternativeA number of items, separated by a bar |.


A bar denotes a choice between several options. In other words, the matching text must include
exactly one of them. For example, either the word Hello or an expression matches the following:
Hello|<exp>

21.4.4

Submatch Labels

You can give groupings and options in a match expression a submatch label. A submatch label serves as
a symbolic name for the text matched by the grouping or the option, and lets you refer to it from the
macro body by name rather than by number.
A submatch label has the following form:
(<LABEL>item...)
[<LABEL>item...]
where
LABEL is a sequence of capital letters and underscores only, beginning with a capital letter.
For example, the following grouping has submatch label <WORD>:
(<WORD>Hello|Bye).

In this example, the option has submatch label <OPT_EXP>:


[<OPT_EXP><firstexp>**<secondexp>]

See Also

Submatches on page 1115

21.4.5

Special Literal Characters

Parentheses, square brackets, curly brackets, double quotes and semicolons have a fixed syntactic
function in e. They cannot appear just anywhere as literal characters in a match expression. They must
appear only as described below.

21.4.5.1 Parentheses, Square Brackets and Curly Brackets


These characters signify subordination of one construct to another unless they appear inside double
quotes. In a match expression they must

Appear in balanced pairs. (For example, a left parenthesis cannot appear without a right parenthesis)

Specman e Language Reference


1999-2015

1113
.

Product Version 15.1


All Rights Reserved.

Enclose a single syntactic argument (with or without repetition)

The following match expression is legal and denotes the word Hello, followed by a comma, a white
space, and an expression enclosed in parentheses:
"Hello, \(<exp>\)"

The following match expression is also legal and denotes a sequence of actions separated by commas,
enclosed in curly brackets.
"{<action>,...}"

The following match expression is illegal because has a left curly bracket without a right bracket:
"abc { 123"

The following match expression is illegal because what appears inside the parentheses is not a syntactic
argument:
"\(Hello\)"

21.4.5.2 Double Quotes


Double quotes can be used in only one way to enclose the syntactic type any. Thus, the only legal
use of double quotes as literals is as follows:
\"<any>\"

Because <any> matches any sequence of characters, the example above matches anything enclosed in
double quotes.
Of course, the syntactic argument <any> can have a tag, for example:
\"<someany>\"

21.4.5.3 Semicolons
A semicolon can be used only as the separator of a repetition syntactic argument inside curly brackets.
Any other use of a semicolon in a match expression is illegal.
The following match expression is legal:
"{<command>;...}"

The following match expressions are illegal:


"Hello;world"
"\[<exp>;...\]"

Specman e Language Reference


1999-2015

1114

Product Version 15.1


All Rights Reserved.

21.4.6

Submatches

When a match expression matches a string in the code, certain substrings of that string are submatches
of that match. The submatches are identified by the following match expression elements:

Groupings

Options

Syntactic arguments (with or without repetition)

If any of the above is not actually matched, then the corresponding submatch is empty. For example, if a
syntactic argument appears inside an option in the match expression, but does not appear in the matched
string, then the corresponding submatch is empty.
Submatches are numbered by their order of occurrence in the match expression, from left to right,
starting from 1. For example in the following match expression, the entire grouping (including the
<exp> and the optional Hello) is submatch number 1, the <exp> is submatch number 2, and the
optional Hello is submatch number 3:
"My (<exp>[Hello])"

You can use submatch numbers to refer to submatches from the macro body. However, it is better to use
submatch labels and syntactic argument names instead.
Note

The maximum total number of allowed submatches in a macro is 50.

21.4.7

Problematic Match Expressions

Following are the causes of some common problems with match expressions:

Specifying literal backslash characters incorrectly in match expressions


Within a macro definition, a match expression appears as an e literal string inside a pair of double
quotes. That string is first treated by the Specman parser as any usual string, including the special
treatment of escaped characters such as \n or \", and only then is passed on to the match
expression parser. This might cause confusion, in some cases. For example, if you write a macro to
match a backslash followed by the letter a, you have to write it three times rather than two:
"\\\a"

and if it is followed by the letter t, you have to write the backslash four times:
"\\\\t"

See Literal String on page 40 for more information on the escape sequences allowed in e strings.

Failing to escape double quotes in match expressions


A non-escaped double quote is treated as the closing quote of the match expression itself, rather
than a literal within it.

Specman e Language Reference


1999-2015

1115
.

Product Version 15.1


All Rights Reserved.

Failing to escape literal parenthesis and square brackets


Parentheses and square brackets need to be escaped in the match expression to be taken as literals.
Otherwise, they are taken as grouping and option operators.

Attempting to match two or more subsequent spaces


Such usage is never matched. For example, the following match expression:
"Hello, [ world]!"

matches Hello, ! but does not match Hello, world!.

Placing white spaces at the beginning or end of a match expression


Because Specman removes any white spaces preceding or trailing a construct before attempting to
match it, no construct matches a match expression with spaces at either end of it. For example, the
following match expression is illegal:
" Hello, world!"

Empty match expressions are also illegal.

Failing to use a line continuation character in multi-line match expressions


To continue a match expression over multiple lines, put the line continuation character \ at the end
of each line except the last, just as you do with any string in e.

Failing to use unique names for syntactic arguments


Any syntactic argument referenced from the macro body must have a name that is unique within the
same match expression. However, it is not necessary for each referenced syntactic argument to have
a tag. For example, the syntactic arguments <exp> and <otherexp> have unique names.
Also, if some syntactic arguments are not referenced from the macro body, they can have the same
name. For example, it is OK to use <exp> without a tag more than once in the same match
expression if neither expression is referenced from the macro body.

See Also

Special Literal Characters on page 1113

Regular Expression Operators in Match Expressions on page 1112

21.4.8

Examples

Below are some examples for legal match expressions.

Specman e Language Reference


1999-2015

1116

Product Version 15.1


All Rights Reserved.

Example 1
This match expression matches a construct that consists of an optional keyword, either private or
public, followed by white spaces, then a name followed by a colon, optional white spaces, a type, and
then optionally followed by an equal sign, possibly surrounded by white spaces, and an expression.
"[<MOD>(private|public) ]<name>:[ ]<type>[[ ]=[ ]<exp>]"

The label <MOD> is a submatch label for the optional private or public keyword, including the
white space after them.
Note The space at the end of the first option cannot be replaced by a space outside the option, because
then the match expression does not match an input without one of those keywords.
Some inputs that are matched by this match expression:
x:int
private y: uint
public abc:string ="Hello"

Example 2
This match expression matches a construct that consists of a list of expressions separated by commas
and enclosed in square brackets, followed by white spaces, anything within double quotes, and another
sequence of expressions separated by white spaces.
"\[<exp>,...\] \"<any>\"<moreexp> ..."

Some inputs that are matched by this match expression:


[ x : y+5] "Hello, world" 5
[ ] "xyz"i j

6 7

See Also

Overview of e Macros on page 1081

define as on page 1085

define as computed Macro on page 1096

Tracing Macro Expansion on page 1117

21.5 Tracing Macro Expansion


To see how macros are expanded by the parser:
1.

Type the following Specman command at the cmd-prompt> prompt:

Specman e Language Reference


1999-2015

1117
.

Product Version 15.1


All Rights Reserved.

trace reparse

2.

If necessary, reload the e code that contains the macro usage that you want to see expanded.

For commands typed at the prompt and for files loaded into Specman, any macro expansion that is done
after you enter the trace reparse command is printed to the screen.
Below are shown the results of using the macro <max3exp> defined in Example 1 on page 1089.
cmd-prompt> var x: int
cmd-prompt> x = max3 1, 2, 3
D> <max3exp> max3 1, 2, 3
D> reparsed as: max(1, max( 2, 3))
cmd-prompt> print x
x = 3
cmd-prompt> x = max3 10, 15, 5
D> <max3exp> max3 10, 15, 5
D> reparsed as: max(10, max( 15, 5))
cmd-prompt> print x
x = 15

Note trace reparse shows how macros are actually being expanded during parsing and works for
commands as well as loaded e code. However, you can also use the show macro_call command at run
time to display macro expansion for loaded e code. Use show macro_call for run-time macro debugging.

See Also

Overview of e Macros on page 1081

define as on page 1085

define as computed Macro on page 1096

Match Expressions in e Macros on page 1109

show macro in the Specman Command Reference

21.6 Macro Error Messages


When a macro definition is loaded, Specman does not check the correctness of the replacement code
itself, except for the correctness of the replacement terms andonly for define as macrossome
general problems, like unbalanced parentheses. Most errors in the replacement code are discovered and
reported only when the macro is actually expanded, at load/compile time or run time
When an error is caused by e code, and that e code is the result of a macro expansion, then the error
message includes a reference to the macro definition code, as well as a reference to the place where the
macro was expanded.

Specman e Language Reference


1999-2015

1118

Product Version 15.1


All Rights Reserved.

Example 1

define as Macro

In the case of a define as macro, the error message identifies the problematic line within the macro
definition code.
macro_definition.e
<'
define <bean'struct_member> "bean <name>[ ]:[ ]<type>" as {
private <name>: <type>;
get_<name> (): <type> is {
return <name>;
};
set_<name> (val: <type>) is {
<name> = value;
--error here at line 8
};
};
'>

macro_usage.e
<'
import macro_definition;
extend sys {
bean a_number: int;

--macro expanded here at line 6

};
'>

Results
Specman> load macro_usage
Loading macro_definition.e
(imported by macro_usage.e) ...
read...parse...update...patch...h code...code...clean...
Loading macro_usage.e ...
read...parse...update...patch...h code...code...
*** Error: No such variable 'value'
at line 8 in macro_definition.e
<name> = value;
expanded at line 6 in macro_usage.e
bean a_number: int;

Specman e Language Reference


1999-2015

1119
.

Product Version 15.1


All Rights Reserved.

Example 2

define as computed Macro

In the case of a define as computed macro, the error message points to the line where the macro
definition begins, not to any problematic line within the definition. For example, if you call the config
frame macro as defined below from the Specman prompt, you see the following message:
Specman> SRAM config frame
*** Error: 'gen' action cannot be invoked interactively, only from a method
in code generated by macro defined at line 2 in @macro_definition
define <configure_frame'action>
expanded from command

macro_definition.e
<
define <configure_frameaction>
"<name> config frame[ <dest_addrnum>]" as computed {
var address_constraint: string;
if !str_empty(<dest_addrnum>) then {
address_constraint =
append(".dest_address == ", <dest_addrnum>, ";");
};
return append("{ \
var f: frame; \
gen f keeping { \
.kind == ", <name>, "; \
.size == 64;",
address_constraint,
"}; \
f.send(); \
} ");
};
>

21.7 Debugging Macros


Debugging macros is very similar to debugging methods in e source code. Debugging of nested macros,
the macro call chain stack, and both define as and define as computed macros are supported. Each
macro call appears to open a new frame, enabling you to follow the history of calls.
For more information on the commands available for debugging macros, see:

configure debugger in the Specman Command Reference

step in the Specman Command Reference

next in the Specman Command Reference

finish in the Specman Command Reference

Specman e Language Reference


1999-2015

1120

Product Version 15.1


All Rights Reserved.

break on call in the Specman Command Reference

break on line in the Specman Command Reference

stack in the Specman Command Reference

show macro in the Specman Command Reference

There are two macro debugging modes.


The definition macro debugging mode is the default macro debugging mode. It enables debugging of
the macros original source code.
The expansion macro debugging mode enables debugging of the macros expanded code.
You can change the macro debugging mode during run-time or during debugging by any of the
following methods:

Use the config debugger command to select the macro debugging mode. For example:
cmd-prompt> config debug -macro_debug_mode=expansion

When in GUI mode, you can select the macro debug mode by using the Macro Debug Mode button
or the Tools Macro Debug Mode command in the debugger GUI.

Notes

You must use the expansion macro debugging mode to debug define as computed macros.
Breakpoints on expanded macro code are relevant only for the specified macro expansion, and do
not apply to the macro code in general. Breakpoints on the original macro code apply to all of its
macro expansions.
While in definition macro debugging mode, using the step command on a define as computed
macro call, execution continues until stopping on the next debuggable action line (either a call from
inside the macro, or the next line after the macro call).
While in expansion macro debugging mode, when execution hits a breakpoint defined in the macro
definition code, the debugger stops on the matching line in the macros expanded code.
While in definition macro debugging mode, when execution hits a breakpoint defined in the macro
expansion code, the debugger stops on the matching line in the definition code. If the macro was a
define as computed macro, the debugger would stop on the macro call.

Example 1

Using the Debug Commands in a Macro

This example demonstrates the use of the step, next, finish, and break on line debugger commands.
<'
define <send_simple_frameaction> send simple frame as {
var f: frame;
// line 3
gen f;
// line 4
f.send();
Specman e Language Reference
1999-2015

1121
.

Product Version 15.1


All Rights Reserved.

};
// line 6
extend sys {
run() is also {
send simple frame;
};
};

// line 9

'>

During debug, if you stop on the call to send simple frame in line 9, the step command directs
debugger focus to the first action in the send_simple_frame macro at line 3. At this point, the step or
next command will direct debugger focus to the next action in line 4. The finish command causes
execution to continue to the end of the macro, where it stops after executing the last action (in line 6).
The stack up command shows the call to send simple frame in line 9.
If you issue the command
(stopped) cmd-prompt> break on line 3

each call to send simple frame causes execution to stop at line 3.

Example 2

Debugging Nested Macros

This example shows the debug flow used with nested macros.
...
<'
define <send_simple_framesaction> send <num> simple frames as {
for i from 1 to <num> do {
send simple frame;
// line 12
};
};
...

Nested macro calls are seen in the call chain stack. When you step into the send_simple_frames
macro, and then step into send simple frame in line 12, a new macro call is added to the debuggers
call stack. Use the stack up and stack down debugging command to browse the call chain.

Example 3

The break on ... Commands and the Macro Debugging Modes

This example shows the use of the break on line and break on call commands. Also shown is the
difference between the macro debugging modes definition and expansion.
<'
define <beanstruct_member> bean <name>[ ]:[ ]<type> as {
private <name>: <type>;
get_<name> (): <type> is {
return <name>; // line 5
};
Specman e Language Reference
1999-2015

1122

Product Version 15.1


All Rights Reserved.

set_<name> (val: <type>) is {


<name> = val;
};
};
struct bean_struct {
bean x: int;
};
'>

A method defined inside a macro can be debugged.


Using the command break on line 5, would set a breakpoint on the line within the macro, and the
debugger would stop before each execution of that line.
Using the command break on call *.get*, would set a breakpoint on the first action in get_x().
Using the definition macro debugging mode, stepping into the get_x() method would step into the
original code. Note that definition is the default macro debugging mode.
Using the expansion macro debugging mode, the expanded code for debugging would be:
get_x(): int is {
return x;
};

Example 4

Debugging Macro Expansion Code

This example shows the use of the expansion macro debugging mode and the use of the break on line
@#expansion_index command.
// time_cmd_macro_def.e
<'
define <time_command'action> time[ <any>] as computed {
if <any> == on {
return({tprint = TRUE; print sys.time;} );
} else if <any> == off {
return(tprint = FALSE);
} else {
error(Usage: time [on|off]);
};
};
'>

// time_cmd_macro_use.e
<'
Specman e Language Reference
1999-2015

1123
.

Product Version 15.1


All Rights Reserved.

extend sys {
tprint: bool;
run() is also {
time on; // line 6
time off; // line 7
time on; // line 8
};
};
'>

Using the show macro command we can obtain information on the macro expansions in the code:
cmd-prompt> show macro in line 6 @time_cmd_macro_use
code:
macro:
match expression:

"time on"
<time_command'action>
"time[ <any>]"

submatch name
matched sub-string
-----------------------------------------------------<any>
"on"
expansion #1
--------------1
{
2
tprint = TRUE;
3
print sys.time;
4
};

cmd-prompt> show macro of line 7 @time_cmd_macro_use


code:
macro:
match expression:

"time off" at line 7 in @time_cmd_macro_use


<time_command'action> at line 3 in @time_cmd_macro_def
"time[ <any>]"

submatch name
matched sub-string
-----------------------------------------------------<any>
"off"
expansion #2
--------------1
tprint = FALSE;

Stepping into lines 5 and 6 steps into different expansion code.


Enable debugging of a macros expanded code:
Specman e Language Reference
1999-2015

1124

Product Version 15.1


All Rights Reserved.

cmd-prompt> config debug -macro_debug_mode=expansion

Now, using the command:


cmd-prompt> break on line 3 @#1

causes the debugger to stop on line 3 in the macro call on source line 6 only, and not on source line 8,
even though their expansions are identical.

See Also

show macro in the Specman Command Reference

configure debugger in the Specman Command Reference

break on line in the Specman Command Reference

break on call in the Specman Command Reference

Specman e Language Reference


1999-2015

1125
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

1126

Product Version 15.1


All Rights Reserved.

22

Preprocessor Directives

This chapter contains the following sections:

#ifdef, #ifndef on page 1127. You use these preprocessor directives used to control e processing. The
preprocessor directives check for the existence of a #define for a given name:

#ifdef directive: if a given name is defined, use the attached code, otherwise, use different code

#ifndef: if a given name is not defined, use the attached code, otherwise, use different code

The #ifdef and #ifndef directives can be used as statements, struct members, or actions.

#define on page 1130, which defines a Verilog-style macro or a preprocessor directive.

#undef on page 1133, which removes the definition of a Verilog-style macro or a preprocessor

directive.

Predefined Preprocessor Flags for Specman Version Number on page 1135. You can use these

preprocessor flags in e code or in C code.

See Also

Chapter 24 Importing e Files

Using the C Interface in the Specman Integrators Guide

22.1 #ifdef, #ifndef


Purpose
Define a preprocessor directive

Specman e Language Reference


1999-2015

1127
.

Product Version 15.1


All Rights Reserved.

Category
Preprocessor directive

Syntax
#if[n]def [`]name then {e-code}
[#else {e-code}]
Syntax Example
#ifdef MEM_LG then {
import mml.e;
};

Parameters
name

Without a backtick, a name defined in a #define statement. For information about


#define, see #define on page 1130.
With a backtick (`name), a name defined with a Verilog `define directive, or in a
Specman #define statement where the name is defined in Verilog style.

e-code

e code to be included based on whether the directive has been defined.

Description
The #ifdef and #ifndef preprocessor directives are used together with #define directives to cause the e
parser to process particular code or ignore it, depending on whether a given directive has been defined.

The #ifdef syntax checks whether the directive has been defined and, if it has, includes the code
following then.
The #ifndef syntax checks whether the directive has been defined and if it has not, includes the code
following then.

The optional #else syntax provides an alternative statement when the #ifdef or #ifndef is not true. For
#ifdef, if the directive has not been defined, the #else code is included. For #ifndef, if the directive has
been defined, the #else text is included.

Example 1
In this example, #ifdef is used as statements. The module named t_1.e contains the statement define
test_C. Neither test_A nor test_B is defined anywhere. Thus, only the t_4.e module is imported
by the #ifdef statements.
Specman e Language Reference
1999-2015

1128

Product Version 15.1


All Rights Reserved.

<'
import t_1.e;// defines test_C;
#ifdef test_A then {
import t_2;
}
#else {
#ifdef test_B then {
import t_3;
};
#ifdef test_C then {
import t_4;
};
};
'>

Example 2
In this example, #ifdef is used as a struct member. The module contains the statement define test_C.
Neither test_A nor test_B is defined anywhere. Thus, only the keep t_data in [300..399] constraint
is applied to the generator after the #ifdef statements have been processed.
<'
define test_C;
struct exa_str {
t_data: uint;
#ifdef test_A then {
keep t_data in [100..199];
}
#else {
#ifdef test_B then {
keep t_data in [200..299];
};
#ifdef test_C then {
keep t_data in [300..399];
};
};
};
'>

Example 3
In this example, #ifdef is used as an action. The module contains the statement define test_C. Neither
test_A nor test_B is defined anywhere. Thus, only the gen t_data keeping it in [300..399] action
is applied by the #ifdef statements.
Specman e Language Reference
1999-2015

1129
.

Product Version 15.1


All Rights Reserved.

<'
define test_C;
struct t_str {
!t_data: int;
t_meth() is {
#ifdef test_A then {
gen t_data keeping {it in [100..199]};
}
#else {
#ifdef test_B then {
gen t_data keeping {it in [200..299]};
};
#ifdef test_C then {
gen t_data keeping {it in [300..399]};
};
};
};
};
'>

Example 4
In this example, #ifdef is used as a command in a .ecom batch file. In the first #ifdef line, the specman()
routine is needed because that is the way to execute a command, config gen in this case, from inside an
action block. In the second #ifdef line, the specman() routine is not needed, since the action block
contains a routine, out(), rather than a command.
// file: test_A.ecom
load test_A
#ifdef TEST_LARGE then {specman("config gen -max_structs = 50000")}
#ifdef TEST_A then {out("This is test_A.")}
test

See Also

Chapter 24 Importing e Files

22.2 #define
Purpose
Define a Verilog-style macro or a pre-processing directive
Specman e Language Reference
1999-2015

1130

Product Version 15.1


All Rights Reserved.

Category
Statement

Syntax
#define [`]name [replacement]
Syntax Example
#define PLIST_SIZE 100;
#define INTERACTIVE_DEBUG;

Parameters
name

Any e name.
A name specified without the replacement parameter is used for conditional code
processingit causes an #ifdef preprocessor directive found later in the e code with the
name as its argument to evaluate to TRUE. See #ifdef, #ifndef on page 1127 for more
information.
When replacement is specified, the parser substitutes the replacement for the name
everywhere the name appears, except in strings.
The name can be preceded with a backtick (`) to make the name look like a Verilog
`define name, but it is treated the same as a name without a backtick.
The name is case sensitive: LEN is not the same as len.

replacement

Any syntactic element, for example, an expression or an HDL variable. Replaces the
name wherever the name appears in the e code that follows the #define statement.
Note

Use parentheses in the replacement string to ensure proper associativity.

For example, the following two replacement strings are interpreted differently:
#define LX 2*len+m;
#define LX 2*(len+m);

In an expression such as lenx = `LX, the replacement string in the first case becomes
2 * len + m, while in the second case, it becomes lenx = 2*len + 2*m.

Specman e Language Reference


1999-2015

1131
.

Product Version 15.1


All Rights Reserved.

Description
With a replacement, defines a Verilog-style macro that replaces the name wherever it occurs in the e
code.
With no replacement, specifies a directive that can be used in #ifdef preprocessor directives for
conditional code. A subsequent evaluation of an #ifdef that has the name as its argument returns TRUE.

Limitations and Notes

A #define statement only applies to e code that is loaded after the #define.
When a #define statement is spread over multiple lines, each line must end with a backslash character
(\), except the last last line which ends with a semicolon (;) like any statement.
The replacement must not contain the name. A statement like the following causes a compilation error:
#define bus_width top.bus_width;

// Compilation error

This causes the parser to recursively replace bus_width with top.bus_width. That is,
bus_width would become top.bus_width, as desired, but then top.bus_width would become
top.top.bus_width, and so on.

You can define and remove directives at runtime. See #define / #undef in the Specman Command
Reference for more information.
If a name is already defined with #define, you need to first undefine it with #undef before redefining
it. However, you can redefine the name without undefining it first if the replacement string used in
the new directive is identical to the one used in the old directive. For example, #define X 5 that
follows #define X 5 used earlier has no effect, because X is defined with the value 5 in both
instances.

Example 1
The following are Verilog-style macro definitions:
#define
#define
#define
#define
#define
#define
#define
#define

OFFSET 5;
FIRST (OFFSET + 1);
SECOND (FIRST + 1);
MULTIPLY_I_J i * j;
LG_CASE;
bus_width 64;
bus_width_1 'top.bus_wire';
bus_width_2 top.bus_wire;

To use a Verilog-style macro, refer to name. You can use the definitions given above as follows:
struct example {
test_defines() is {
var i: int;
Specman e Language Reference
1999-2015

1132

Product Version 15.1


All Rights Reserved.

var j: int;
print OFFSET, FIRST, SECOND; // Prints 5,
i = 5;
j = 6;
print MULTIPLY_I_J + 3;
// Prints 33
#ifdef LG_CASE then {
i = j * 2;
print i;
// Prints 12
}
#else {
out(LG_CASE is not defined);
};
j = `bus_width * 2;
print j;
// Prints 128

6, 7

(5 * 6 + 3)

(6 * 2)

(64 * 2)

};
};

Note

See Example on page 1134 for an example of defining a preprocessor directive.

See Also

#undef on page 1133

#define on page 1130

22.3 #undef
Purpose
Remove a preprocessing directive

Category
Statement

Syntax
#undef name
Syntax Example
#undef INTERACTIVE_DEBUG;

Specman e Language Reference


1999-2015

1133
.

Product Version 15.1


All Rights Reserved.

Parameters
name

Any e name.
This is used for conditional code processing. An #ifndef preprocessor directive later in
the e code that has the name as its argument evaluates to FALSE. See #ifdef, #ifndef on
page 1127 for more information.
The name is case sensitive: LEN is not the same as len.

Description
Removes a preprocessing directive that was defined using the #define statement. The #undef statement
can be entered at any point in the e code. The specified directive is not recognized from the point where
the #undef statement appears onward. The effect is propagated to all files that are loaded after the
#undef statement is encountered.

Notes

#undef cannot be used without the # character.

You cannot use #undef to remove a Verilog-style macro that begins with a backtick (`).

If the directive was not previously defined, #undef has no effect it is not an error.

A directive that is undefined in a compiled e module is not accessible to the C interface at any time.

A directive that has been undefined can be redefined later, with any value. The last value is accessible
to the C interface.
You can define and remove directives at runtime. See #define / #undef in the Specman Command
Reference for more information.

Example
This example has two e files, my_design.e and external_code.e, and the following appears in the
my_design.e module:
<'
struct semaphore {
// Contents of the user-defined semaphore struct
};
'>

The following appears in the external_code.e module:


<'
extend sys{
Specman e Language Reference
1999-2015

1134

Product Version 15.1


All Rights Reserved.

event clk is rise('~/top/clk')@sim;


sem: semaphore; // Uses the built-in Specman semaphore struct
increment()@clk is {
sem.up()
};
};
'>

In the external_code.e file, the built-in Specman struct is used. In order to be able to use the built-in
semaphore struct, you can put the following in a top file, which imports both my_design.e and
external_code.e. This first defines a directive that replaces semaphore with my_semaphore, and
then, after the my_design.e module is loaded, undefines semaphore so that the built-in semaphore
struct is used from that point on:
<'
#define semaphore my_semaphore;
import my_design.e;
#undef semaphore;
import external_code.e;
'>

See Also

#define on page 1130

22.4 Predefined Preprocessor Flags for Specman


Version Number
The following describe the predefined preprocessor flags:

SPECMAN_VERSION_nn_nn on page 1136

SPECMAN_FULL_VERSION_nn_nn_nnn on page 1136

SPECMAN_VERSION_nn_nn_OR_LATER on page 1137

See Also

#ifdef, #ifndef on page 1127

#define on page 1130

Using the C Interface in the Specman Integrators Guide

Specman e Language Reference


1999-2015

1135
.

Product Version 15.1


All Rights Reserved.

22.4.1

SPECMAN_VERSION_nn_nn

The SPECMAN_VERSION_nn_nn preprocessor flag identifies the release number for a specific
Incisive Base release, for example 10.20.
For a given release, there is only one SPECMAN_VERSION_nn_nn, where nn_nn is the Incisive Base
release main version number, for example 10.20, with the . character replaced by an underscore, for
example 10_20.
This flag is defined in Specman as well as in specman_.h and in any C header file generated by
sn_compile.sh.

Example
<'
#ifdef SPECMAN_VERSION_10_20 then {
import new_code.e;
}
#else {
import old_code.e;
}
'>

You can also execute actions at the Specman prompt, based on the version number. For example, the
following command activates IntelliGen as the default generator for Specman 10.20:
Specman> #ifdef SPECMAN_VERSION_10_20 {specman("config gen -default_generator
= IntelliGen")}

22.4.2

SPECMAN_FULL_VERSION_nn_nn_nnn

The SPECMAN_FULL_VERSION_nn_nn_nnn preprocessor flag identifies the full release number for
a specific Incisive Base, Update, or Hotfix release, for example 10.20.025, where nn_nn-nnn is the
release number with the . character replaced by an underscore, for example 10_20_025.
This flag is defined in Specman as well as in specman_.h and in any C header file generated by
sn_compile.sh.

Example
The following example show how you could define a 10.2 environment such that projects run under
10.20.25 would use IntelliGen as the default generator:
// ...
#ifdef SPECMAN_FULL_VERSION_10_20_025 then {
Specman e Language Reference
1999-2015

1136

Product Version 15.1


All Rights Reserved.

set config (gen, default_generator, IntelliGen);

22.4.3

SPECMAN_VERSION_nn_nn_OR_LATER

The SPECMAN_VERSION_nn_nn_OR_LATER preprocessor flag is useful for creating reusable


verification components that apply to multiple Specman versions. From a user perspective, such
components are version-independent.
For example, if you are developing an e UVC that uses a new feature introduced only in Specman 10.20,
use SPECMAN_VERSION_10_20_OR_LATER to keep the e UVC backward compatible with older
Specman versions (as illustrated in the example below). Using the OR_LATER variant lets you avoid
the need to change it for any later Specman version.

Example
<'
#ifdef SPECMAN_VERSION_10_20_OR_LATER then {
import new_code.e;
}
#else {
import old_code.e;
}
'>

Specman e Language Reference


1999-2015

1137
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

1138

Product Version 15.1


All Rights Reserved.

23

Predefined Methods

A significant part of Specman functionality is implemented as set of predefined methods defined


directly under the global and sys structs. These methods are described in the following sections:

Global Methods on page 1140

Methods of sys on page 1157

Specman has a predefined struct, any_struct, which in turn has many predefined methods. All
user-defined structs inherit from any_struct, so all its predefined methods are available to any struct you
define. Some of these methods can be extended to add functionality, and some of them are empty,
allowing you to define their function.
There is also a predefined type any_unit, which is derived from any_struct. any_unit is the base type
implicitly used in user-defined unit types, so predefined methods for any_struct are also available for
any user-defined unit.
The predefined methods for any struct or unit are described in:

Predefined Methods of Any Struct or Unit on page 1176

Predefined Attributes and Methods for Any Unit on page 282

Unit-Related Predefined Methods for Any Struct on page 307

The predefined structs global.covers, global.scheduler, and global.simulator each contain predefined
methods specific to their purpose, as described in:

Coverage Methods on page 1232

Scheduler Methods on page 1260

Simulation-Related Methods on page 1272

In addition, the semaphore and locker predefined struct types provide predefined methods that are
useful in controlling TCMs and in controlling resource sharing between TCMs.

Specman e Language Reference


1999-2015

1139
.

Product Version 15.1


All Rights Reserved.

Semaphore and Locker Methods on page 1276

Finally, there are pseudo-methods. Calls to pseudo-methods look like method calls. However, they are
associated not with struct expressions, but with other kinds of expressions. Pseudo-methods are
described in:

Pseudo-Methods on page 1292

Time Conversion Pseudo-Methods on page 1297

Chapter 25 List Pseudo-Methods

See Also

Unit-Related Predefined Routines on page 317

File Routines on page 1555

Chapter 27 Predefined Routines

23.1 Global Methods


Most of the predefined global methods are called automatically as part of the test command. It is not
recommended to call or extend the predefined methods of global.
Many of these global methods call a method with the same name in sys. You can extend these related
methods of sys, but you should not call them. Some of the methods in sys have a predefined body that
calls predefined empty methods in the units or structs instantiated in sys. You can extend these
predefined methods to specify the desired behavior at that test phase.
The global methods that are called automatically as part of the test command are described in the
following sections:

Test Phase Flow on page 1141

Global Method start_test() on page 1144

Global Method generate_test() on page 1144

Global Method setup_test() on page 1145

Global Method run_test() on page 1145

Global Method extract_test() on page 1146

Global Method check_test() on page 1147

Global Method finalize_test() on page 1147

The following are also global methods:

Global Method get_timescale() on page 1148

Specman e Language Reference


1999-2015

1140

Product Version 15.1


All Rights Reserved.

Global Method is_gui() on page 1149

Global Method print_stack_trace() on page 1149

Global Method simulator_exists() on page 1151

Global Method simulator_save() on page 1152

Global Method sn_plusarg_exists() on page 1152

Global Method sn_plusarg_value() on page 1154

Global Method update_sys_time() on page 1156

23.1.1

Test Phase Flow

Most of the methods of the global struct control the execution of the phases of a test run, including
setting up the test and test data, executing the test, checking the test results, and finalizing the test data.
These methods are invoked when you enter the test command or any of the other test phase commands,
such as setup, generate, run, and check. In turn these methods invoke related test-phase predefined
methods of sys and of any struct or unit.
The test phases and the predefined methods associated with each phase are shown in Figure 23-1 on
page 1142. The following sections describe the test phase methods in detail. (Please use the hyperlinks
to navigate between the two sections of the graphic.)

Specman e Language Reference


1999-2015

1141
.

Product Version 15.1


All Rights Reserved.

Figure 23-1
load phase

Load and Start Test Phases and Predefined Methods


sys.init()

test phase - global.do_test()


start phase - global.start_test()
generate phase - global.generate_test()
setup phase - global.setup_test()
sys.wave_setup()
struct.init()

sys.setup()

struct.pre_generate()
struct.post_generate()

sys.generate()
elaborate phase

sys.connect_pointers()
unit.connect_pointers()
sys.connect_ports()
unit.connect_ports()
sys.check_generation()
unit.check_generation()
unit.elaborate()
Start test

run phase - global.run_test()


check phase - global.extract_test() global.check_test()
finalize phase - global.finalize_test()

Specman e Language Reference


1999-2015

1142

Product Version 15.1


All Rights Reserved.

load phase

test phase - global.do_test()


start phase - global.start_test()

run phase global.run_test()

sys.run()

Start simulation
Run TCMs

struct.run()

on-the-fly
generation

struct.init()
struct.pre_generate()
struct.post_generate()

stop_run()
check phase global.extract_test()
global.check_test()

struct.quit()

sys.extract()
sys.check()

finalize phase global.finalize_test()

sys.finalize()

struct.extract()
struct.check()

struct.finalize()

The following sections describe the function of each global method in more detail:

Global Method start_test() on page 1144

Global Method generate_test() on page 1144

Global Method setup_test() on page 1145

Global Method run_test() on page 1145

Global Method extract_test() on page 1146

Global Method check_test() on page 1147

Global Method finalize_test() on page 1147

Specman e Language Reference


1999-2015

1143
.

Product Version 15.1


All Rights Reserved.

23.1.2

Global Method start_test()

Function
Prepares Specman to start the simulation run.
This method is called when you issue a test or start command from the Specman command line.

Suggested Use
You should not extend or modify the start_test() method. Instead, you can extend the post_generate()
method of a particular struct if you need to perform some task after generation and before starting the
run.

See Also

Test Phase Flow on page 1141

post_generate() on page 658

23.1.3

Global Method generate_test()

Function
Performs pre-run generation by calling sys.generate() and the following predefined methods of every
struct under sys:
1.

struct.init()

2.

struct.pre_generate()

3.

struct.post_generate()

This method is called when you issue a test, start, or generate command from the Specman command
line.

Usage
Do not extend or modify the generate_test() or the sys.generate() method. Instead, you can modify or
extend the init(), pre_generate(), or post_generate() method of a particular struct to perform
initialization or to setup or finalize generation.

Specman e Language Reference


1999-2015

1144

Product Version 15.1


All Rights Reserved.

Note When you are running in UVM (or OVM) modefor example, when config simulation
-target_ml_lib=UVM or you are running irun with the flag -uvmtest, -uvm_top, or -ml_uvmyou
must not extend or modify generate_test() or the sys.generate() method. Otherwise, you will get an
error.

See Also

Test Phase Flow on page 1141

The init() Method of any_struct or any_unit on page 1186

pre_generate() on page 656

post_generate() on page 658

23.1.4

Global Method setup_test()

Function
Initializes test parameters, such as the initial seed for random generation.
This method is called automatically when you issue a test, start, generate or setup command from the
Specman command line. In turn, it invokes sys.wave_setup() and sys.setup().

Suggested Use
It is not recommended to extend setup_test(). If you need to perform a task before generation is run, you
can extend sys.wave_setup() or sys.setup().

See Also

Test Phase Flow on page 1141

The setup() Method of sys on page 1161

The wave_setup() Method of sys on page 1159

23.1.5

Global Method run_test()

Function
Executes sys.run() and for every struct or unit under sys in depth-first field order, executes the structs
run() method.
This method is called when you issue a test or run command from the Specman command line.
Specman e Language Reference
1999-2015

1145
.

Product Version 15.1


All Rights Reserved.

Usage
Do not extend or modify the run_test() method. Instead, you can modify or extend sys.run() or the
run() method of a particular struct to start any TCM that you want to begin execution when simulation
starts.
Note When you are running in UVM (or OVM) modefor example, when config simulation
-target_ml_lib=UVM or you are running irun with the flag -uvmtest, -uvm_top, or -ml_uvmyou
must not extend or modify generate_test() or the sys.generate() method. Otherwise, you will get an
error.

See Also

Test Phase Flow on page 1141

The run() Method of sys on page 1162

The run() Method of any_struct or any_unit on page 1192

23.1.6

Global Method extract_test()

Function
Collects data from the DUT before the post-run checking is performed.
This method is called when you issue a test or check command from the Specman command line. It is
also called under the following conditions:

When a run is stopped by a call to stop_run()

When a run is stopped by a simulator exit command

When a DUT error occurs and the check effect is ERROR_AUTOMATIC

Suggested Use
You should not extend or modify the extract_test() method. Instead, you can modify or extend
sys.extract() or the extract() method of a particular struct to perform any tasks you want completed
before checking is performed.

See Also

Test Phase Flow on page 1141

The extract() Method of sys on page 1163

The extract() Method of any_struct or any_unit on page 1183

Specman e Language Reference


1999-2015

1146

Product Version 15.1


All Rights Reserved.

23.1.7

Global Method check_test()

Function
Runs check() for every struct under sys.
This method is called when you issue a test or check command from the Specman command line. It is
also called under the following conditions:

When a run is stopped by a call to stop_run()

When a run is stopped by a simulator exit command

When a DUT error occurs and the check effect is ERROR_AUTOMATIC

Suggested Use
Do not extend or modify the check_test() method. Instead, you can extend the check() method of a
particular struct, or to perform checking of global data, you can extend the sys.check() method.

See Also

Test Phase Flow on page 1141

The check() Method of sys on page 1164

The check() Method of any_struct or any_unit on page 1177

23.1.8

Global Method finalize_test()

Function
Finalizes the test data, including the emitting of the session.end_of_test event and the writing of
coverage information.

Suggested Use
Do not extend or modify the finalize_test() method. Instead, you can extend sys.finalize() or the
finalize() method of a particular struct to perform any tasks you want completed after checking has been
performed.
This method is called when you issue a test or finalize command from the Specman command line. It is
also called under the following conditions:

When a run is stopped by a call to stop_run()

Specman e Language Reference


1999-2015

1147
.

Product Version 15.1


All Rights Reserved.

When a run is stopped by a simulator exit command

When a DUT error occurs and the check effect is ERROR_AUTOMATIC

See Also

Test Phase Flow on page 1141

The finalize() Method of sys on page 1165

The finalize() Method of any_struct or any_unit on page 1185

23.1.9

Global Method get_timescale()

Purpose
Returns the current Specman timescale.

Category
Global predefined method

Syntax
get_time_scale() : string
Syntax Example
get_timescale();

Description
The get_timescale() method returns the time units used to represent the time in sys.time and
sys.realtime.

See Also

Scalar Types on page 138

Sys Struct on page 56

Specman e Language Reference


1999-2015

1148

Product Version 15.1


All Rights Reserved.

23.1.10 Global Method is_gui()


Purpose
Identifies whether Specman is in GUI mode.

Category
Global predefined method

Syntax
global.is_gui() : bool
Syntax Example
is_gui();

Description
The is_gui() method returns TRUE if Specman is in GUI (SimVision) mode and FALSE if Specman is
in non-GUI mode.
Note Specman does not have to be started in GUI mode for this method to succeed. This method also
returns the correct result if Specman is connected to (or disconnected from) SimVision in the middle of
a batch run.

23.1.11 Global Method print_stack_trace()


Purpose
Print the current user stack trace to the Specman log file.

Category
Global predefined method

Syntax
print_stack_trace()

Specman e Language Reference


1999-2015

1149
.

Product Version 15.1


All Rights Reserved.

Syntax Example
print_stack_trace();

Description
The print_stack_trace() method prints the current user stack trace to the log file. It is generally used in
batch mode to identify the source of a DUT error. The user stack trace that is shown is in the same
format as the user stack trace shown in a specman.err file (the file generated when Specman encounters
an error that stops the run) and is created using the same OS stack trace mechanism. This means that the
result is platform dependent, and might not necessarily match what the show stack command would
print once Specman stops in debugger; in some situations the information might be partial or not
available at all.
To use this method, extend the dut_error_struct.write() method to call print_stack_trace(). A trace of
the stack at the moment of the dut_error is returned.
Note Creation of the output takes significant CPU time. However, unlike running with debugger, its
presence does not affect the performance of other running code.

Example
extend dut_error_struct {
write() is also {
print_stack_trace();
};
};

Example Result
Following is an example of the output to the log file when Specman encounters a DUT error. The user
stack trace starts with the line ( 0) global.print_stack_trace.
*** Dut error at time 0
Checked at line 25 in @test1
In XYZ_packet-@8.parity_check():
(
(
(
(
(
(
(
...

0)
1)
2)
3)
4)
5)
6)

global.print_stack_trace
dut_error_struct.write.also at line 32 in @test1
XYZ_packet.parity_check at line 18 in @test1
sys.check_packets at line 42 in @test1
sys.run.also at line 52 in @test1
specman run
specman

Specman e Language Reference


1999-2015

1150

Product Version 15.1


All Rights Reserved.

See Also

dut_error_struct on page 594

23.1.12 Global Method simulator_exists()


Purpose
Identify whether a simulator is available to work with Specman.

Category
Global predefined method

Syntax
simulator_exists()
Syntax Example
simulator_exists();

Description
Returns TRUE if a simulator is available to run with Specman. If no simulator is set up to run with
Specman, returns FALSE.
Note If the simulator adapter that is available is the OSCI adapter in slave mode, this method might
return FALSE, even though the OSCI adapter is available to run with Specman.

Example
extend sys{
if (simulator_exists()) {
// Code for running Specman with
// the simulator goes here.
} else {
// Code for running Specman
// standalone goes here.
};
};

Specman e Language Reference


1999-2015

1151
.

Product Version 15.1


All Rights Reserved.

23.1.13 Global Method simulator_save()


Purpose
Saves the IES simulator and Specman states.

Category
Global predefined final method
Note The global predefined method simulator_save() has been replaced by the predefined TCM
simulator_save() under sys. The global version of this method is being deprecated and will not be
available in a future release. Use The simulator_save() TCM of Sys on page 1171 instead.

23.1.14 Global Method sn_plusarg_exists()


Purpose
Determines if a particular argument is a +plusarg argument on the command line (that is, an argument
being passed to the e program via the command line).

Category
Global predefined method

Syntax
sn_plusarg_exist(arg : string) : bool
Syntax Example
debug = sn_plusarg_exists("debug");

Description
A plusarg is a series of characters preceded by a + sign and terminated either by an = sign or a space.
This method returns TRUE if the argument in the command line is a +plusarg; otherwise, it returns
FALSE.
Note

The preceding + sign and the terminating = sign or space are not part of the plusarg.

Specman e Language Reference


1999-2015

1152

Product Version 15.1


All Rights Reserved.

Example 1
Given a command line with the following: "+debug +count=100"

sn_plusarg_exists("debug") will return TRUE


sn_plusarg_exists("count") will return TRUE
sn_plusarg_exists("foo") will return FALSE
sn_plusarg_exists("deb") will return FALSE
sn_plusarg_exists("c") will return FALSE
sn_plusarg_exists("count=100") will return FALSE

Example 2
The following code generates a list of integers. Adding debug printouts can be controlled by a command
line plusarg option.
<'
extend sys {
!debug: bool;
l_lower_limit: int;
l_upper_limit: int;
keep l_lower_limit < l_upper_limit;
keep l_lower_limit > -100;
keep l_upper_limit < 100;
l: list of int;
keep for each in l {
it >= l_lower_limit;
it <= l_upper_limit;
};
post_generate() is also {
debug = sn_plusarg_exists("debug");
if (debug) {
out("size of list - ", l.size());
out("lower limit of values is: ", l_lower_limit);
out("upper limit of values is: ", l_upper_limit);
};
};
run() is also {
out(l);
};
};
'>

Specman e Language Reference


1999-2015

1153
.

Product Version 15.1


All Rights Reserved.

23.1.15 Global Method sn_plusarg_value()


Purpose
Returns the value of a particular +plusarg argument on the command line (that is, an argument being
passed to the e program via the command line).

Category
Global predefined method

Syntax
sn_plusarg_value(arg : string) : string
Syntax Example
var li := sn_plusarg_value("size");

Description
If the command line has an argument in format +plusarg=value, the method will return the value. (The
preceding + sign and the terminating = sign are not part of the plusarg.)
Note If the plusarg has no value assigned (that is, it is not in the format: +plusarg=value, or the value
is empty), the method returns an empty string.

Example 1
Given a command line with the following: +debug +count=100 +testname=my_test
+testfile=

sn_plusarg_value("debug") will return ""

sn_plusarg_value("count") will return "100"

sn_plusarg_value("count").as_a(int) will return 100 (of type integer)

sn_plusarg_value("testname") will return "my_test"

sn_plusarg_value("testfile") will return ""

sn_plusarg_value("foo") will return ""

Specman e Language Reference


1999-2015

1154

Product Version 15.1


All Rights Reserved.

Example 2
The following code generates a list of integers. It has default values for the size of the list and for lower
and upper bounds, but these values may be changed by command line plusarg options.
<'
extend sys {
!l_lower_limit: int;
!l_upper_limit: int;
pre_generate() is also {
l_lower_limit = get_lower_limit();
l_upper_limit = get_upper_limit();
};
l_size(): int is {
var li := sn_plusarg_value("size");
if (li == "") {
result = 10;
}
else {
result = li.as_a(int);
};
};
get_lower_limit(): int is {
var li := sn_plusarg_value("lower_limit");
if (li == "") {
result = 0;
}
else {
result = li.as_a(int);
};
};
get_upper_limit(): int is {
var li := sn_plusarg_value("upper_limit");
if (li == "") {
result = 100;
}
else {
result = li.as_a(int);
};
};

Specman e Language Reference


1999-2015

1155
.

Product Version 15.1


All Rights Reserved.

l: list of int;
keep l.size() == l_size();
keep for each in l {
it >= l_lower_limit;
it <= l_upper_limit;
};
run() is also {
out(l);
};
};
'>

23.1.16 Global Method update_sys_time()


Purpose
Synchronize Specman with the simulation time.

Category
Global predefined method of session.

Syntax
session.update_sys_time()

Description
You call this method from your e code to synchronize with simulation time when control has passed to
the e code before synchronization has occurred.

Example
Suppose the test environment contains some C code that does not perform any synchronization. You can
synchronize time within the e code. For example, suppose the C code dispatches my_method(), as
follows:
PLI_INT16 my_call()
{
...
Specman e Language Reference
1999-2015

1156

Product Version 15.1


All Rights Reserved.

SN_DISPATCH(my_method, inst, my_struct, (inst));


...
}

The e code can synchronize time when it is called, as follows:


my_method() is also {
session.update_sys_time();
...
};

23.2 Methods of sys


This section contains descriptions of the extendable methods of sys:

The init() Method of sys on page 1157

The wave_setup() Method of sys on page 1159

The setup() Method of sys on page 1161

The run() Method of sys on page 1162

The extract() Method of sys on page 1163

The check() Method of sys on page 1164

The finalize() Method of sys on page 1165

The pre_save() Method of sys on page 1166

The pre_restore() Method of sys on page 1167

The post_restore() Method of sys on page 1169

The simulator_save() TCM of Sys on page 1171

The remap_tick_access() Method of sys on page 1173

It is not recommended to extend sys.generate(). Instead, you should extend the related pre_generate()
or post_generate() method of a particular struct or unit. See Predefined Methods of Any Struct or Unit
on page 1176 for more information on these methods.

23.2.1

The init() Method of sys

Purpose
Perform general preparations for the test

Specman e Language Reference


1999-2015

1157
.

Product Version 15.1


All Rights Reserved.

Category
Predefined method for sys

Syntax
[sys.]init()
Syntax Example
extend sys {
init() is also {
out("Performing initialization of sys...");
};
};

Description
This method is called when you load an e file with the load command or when you invoke an extended
Specman executable that contains compiled e code.
It is not invoked when you restore an environment from a save file.
You can extend this method to perform general preparations for the test.

Example
This example illustrates when sys.init() is called from compiled e code.
extend sys {
init() is also {
out("This is sys.init()...");
};
};

Results
bash$ sn_compile.sh top.e
# sn_compile.sh: reading specman ini file - $SPECMAN_HOME/system.specman
#-----------------------------------------------------------# Welcome to sn_compile.sh (version: 3.3b3.0)
# sn_compile.sh: executing with args:
# sn_compile.sh top.e
#-----------------------------------------------------------#-----------------------------------------------------------# Translating using
/export/home/opt/specman33/sn_rel3.3b3.0/solaris/specman
Specman e Language Reference
1999-2015

1158

Product Version 15.1


All Rights Reserved.

#-----------------------------------------------------------#
# Compiling the following files:
# -----------------------------# top.e
#
Welcome to Specman (3.3b3.0) - Linked on Mon Aug 21 13:06:31 2000
Checking license ... OK
Translating top.e ...
read...parse...update...patch...h code...code...clean...save...
Translation complete

#-----------------------------------------------------------# Compiling C modules using gcc


#-----------------------------------------------------------#-----------------------------------------------------------# Compiling Specman main
#-----------------------------------------------------------#-----------------------------------------------------------# Linking 'top' using gcc
#-----------------------------------------------------------# ./top is ready.
bash$ top
Welcome to Specman top (3.3)

Linked on Fri Sep

8 2000

This is sys.init()...
Checking license ... OK
Specman top>

See Also

The init() Method of any_struct or any_unit on page 1186

generate in the Specman Command Reference

23.2.2

The wave_setup() Method of sys

Purpose
Initialize waveform viewer parameters

Specman e Language Reference


1999-2015

1159
.

Product Version 15.1


All Rights Reserved.

Category
Predefined method for sys

Syntax
[sys.]wave_setup()
Syntax Example
wave_setup() is also {
set_config(wave, working_mode, off_line);
};

Description
When you issue a test, start, generate or setup command from the Specman command line, the
global.setup_test() method is called. This method in turn calls sys.wave_setup() method. (See Figure
23-1 on page 1142 for more information on test phases.)
You can extend this method by adding calls to the set_config() method to initialize waveform viewer
configuration parameters. This method is initially empty and is meant to be extended. It is automatically
called before the stubs file is generated, and is therefore the place to set configuration options that affect
the stubs file.

Example
If you are using the MTI waveform viewer and want to use short buffers for errors and messages, in
order to be able to see the messages, you can use wave_setup() to set the buffer lengths as shown in the
following example.
extend sys {
wave_setup() is also {
var buffer_size := 12;
set_config(wave, stub_message_len, buffer_size);
set_config(wave, stub_strings_len, buffer_size);
};
};

See Also

configure wave in the Specman Command Reference

Using a Third-Party Waveform Viewer in Running Specman with Third-Party Tools

setup in the Specman Command Reference

Specman e Language Reference


1999-2015

1160

Product Version 15.1


All Rights Reserved.

23.2.3

The setup() Method of sys

Purpose
Initialize test parameters

Category
Predefined method for sys

Syntax
[sys.]setup()
Syntax Example
setup() is also {
set_config_max(memory, gc_threshold, 100m);
};

Description
When you issue a test, start, generate or setup command from the Specman command line, the
global.setup_test() method is called. This method in turn calls the sys.setup() method to initialize test
parameters, such as the initial seed for random generation, in preparation for running a test. (See Figure
23-1 on page 1142 for more information on test phases.)
You can extend this method to set configuration options. See Extending sys.setup() and
sys.wave_setup() in Running Specman with Incisive Simulator for more information.

Example
extend sys {
setup() is also {
set_config_max(memory, gc_threshold, 100m);
};
};

See Also

set_config_max() on page 317

setup in the Specman Command Reference

Specman e Language Reference


1999-2015

1161
.

Product Version 15.1


All Rights Reserved.

23.2.4

The run() Method of sys

Purpose
Recommended place for starting TCMs

Category
Predefined method for sys

Syntax
[sys.]run()
Syntax Example
run() is also {
start monitor();
};

Description
Can be extended to start user-defined TCMs. The method is initially empty.
The run() methods of all structs under sys are called, starting from sys in depth-first field order, by the
global.run_test() method when you execute a test or a run command.
After this initial pass, when any struct is generated (with the gen action) or allocated (with new), its
run() method is also invoked. This ensures that:

The run() method of each struct instance is called exactly once, thus avoiding multiple instances of
the same started TCM;

TCMs do not start and events do not occur before Specman is ready to accept them;

The run() method is called after generation and uses the generated values.

If you run multiple tests in the same session, the run() method is called once for each test in the session.
The init() method is called only once before the first test.

Note
Starting a TCM before the end of start_test() causes a runtime error.

Specman e Language Reference


1999-2015

1162

Product Version 15.1


All Rights Reserved.

Example
<'
extend sys {
id : int;
monitor() @sys.any is {
while (TRUE) {
wait [2] * cycle;
out("cycle ", sys.time,
" Packet id ", id, " is still running");
};
};
run() is also {
start monitor();
};
};
'>

See Also

The run() Method of any_struct or any_unit on page 1192

start tcm() on page 537

run in the Specman Command Reference

23.2.5

The extract() Method of sys

Purpose
Extract test data

Category
Predefined method for sys

Syntax
[sys.]extract()
Syntax Example
extend sys {
extract() is also {
me.flag = 'top.overflow';
Specman e Language Reference
1999-2015

1163
.

Product Version 15.1


All Rights Reserved.

print me.flag;
};
};

Description
This method is called before the post-run checking is performed when you issue a check or finalize
command from the Specman command line. (See Figure 23-1 on page 1142 for more information on test
phases.)
You can extend this method to extract data from the DUT before checking the test results.

Example
extend sys {
extract() is also {
me.flag = 'top.overflow';
print me.flag;
};
};

See Also

The extract() Method of any_struct or any_unit on page 1183

extract in the Specman Command Reference

23.2.6

The check() Method of sys

Purpose
Perform DUT checks

Category
Predefined method for sys

Syntax
[sys.]check()
Syntax Example
check() is also {
Specman e Language Reference
1999-2015

1164

Product Version 15.1


All Rights Reserved.

check that pending == 0


else dut_error("Still have ", pending, " test(s) to do");
};

Description
This method is called to perform the post-run checking when you issue a check or finalize command
from the Specman command line. (See Figure 23-1 on page 1142 for more information on test phases.)
You can extend this method to perform post-test checks.

Example
extend sys {
!pending: uint;
more_tests() is {pending += 1;};
fewer_tests() is {pending -= 1;};
check() is also {
check that pending == 0
else dut_error("Still have ", pending, " test(s) to do");
};
};

See Also

The check() Method of any_struct or any_unit on page 1177

check in the Specman Command Reference

23.2.7

The finalize() Method of sys

Purpose
Finalize test data

Category
Predefined method for sys

Syntax
[sys.]finalize()

Specman e Language Reference


1999-2015

1165
.

Product Version 15.1


All Rights Reserved.

Syntax Example
extend sys {
finalize() is also {
specman("show cover XYZ_router.log");
};
};

Description
This method is called when you issue a test or finalize command from the Specman command line. It is
called after checking has been performed but before coverage data is written to a file. (See Figure 23-1
on page 1142 for more information on test phases.)
You can extend this method to display or manipulate test data.

Example
extend sys {
finalize() is also {
specman("show cover XYZ_router.log");
};
};

See Also

The finalize() Method of any_struct or any_unit on page 1185

finalize in the Specman Command Reference

23.2.8

The pre_save() Method of sys

Purpose
Perform actions immediately before saving the state

Category
Predefined method for sys

Syntax
[sys.]pre_save(state_name: string[, save_dir: string])

Specman e Language Reference


1999-2015

1166

Product Version 15.1


All Rights Reserved.

Syntax Example
extend sys {
pre_save(save_state:string) is also {
;
};
};

Parameters
state_name

The state filename that is given to the save command.

save_dir

(Optional) The directory path (relative or absolute) to the state file.

Description
Defines actions to be preformed immediately before the execution of a save command. Extend the
pre_save() method using is also to add the actions. This method is invoked automatically by the save
command; do not call it explicitly.

See Also

The pre_restore() Method of sys on page 1167

The post_restore() Method of sys on page 1169

save in the Specman Command Reference

23.2.9

The pre_restore() Method of sys

Purpose
Perform actions immediately before restoring the state

Category
Predefined method for sys

Syntax
[sys.]pre_restore(state_name: string[, save_dir: string])

Specman e Language Reference


1999-2015

1167
.

Product Version 15.1


All Rights Reserved.

Syntax Example
extend sys {
pre_restore(save_state:string) is also {
;
};
};

Parameters
state_name

The state filename that is given to the restore command.

save_dir

(Optional) The directory path (relative or absolute) to the state file.

Description
Defines actions to be preformed immediately before the execution of a restore command. Extend the
pre_restore() method using is also to add the actions. This method is invoked automatically by the
restore command; do not call it explicitly.
Adding actions before and after a restore is required for features of the e environment that require
custom persistency code. Typical cases are when e structs reference external C memory or files. In such
cases, you must explicitly save and recover, or finalize and initialize the data.

Example
The following example uses both pre_restore() and post_restore(). In this example, struct s has an
external pointer that is allocated and freed by C code. If it were not freed before the restore, there would
be memory leaks. If it were not reallocated after the restore, the struct would be inconsistent.
<'
struct s {
allocate_p() is C routine s_allocate_p;
free_p() is C routine s_free_p;
!p: external_pointer;
};
extend sys {
my_s: s;
pre_restore(state_name: string, save_dir: string) is also {
if my_s != NULL {
my_s.free_p();
};
};

Specman e Language Reference


1999-2015

1168

Product Version 15.1


All Rights Reserved.

post_restore(state_name: string, save_dir: string) is also {


if my_s != NULL {
my_s.allocate_p();
};
};
};
'>

See Also

The pre_save() Method of sys on page 1166

The post_restore() Method of sys on page 1169

restore in the Specman Command Reference

23.2.10 The post_restore() Method of sys


Purpose
Perform actions immediately after restoring the state

Category
Predefined method for sys

Syntax
[sys.]post_restore(state_name: string[, save_dir: string])
Syntax Example
extend sys {
post_restore(save_state:string) is also {
;
};
};

Parameters
state_name

The state filename that is given to the restore command.

save_dir

(Optional) The directory path (relative or absolute) to the state file.

Specman e Language Reference


1999-2015

1169
.

Product Version 15.1


All Rights Reserved.

Description
Defines actions to be preformed immediately after the execution of a restore command. Extend the
post_restore() method using is also to add the actions. This method is invoked automatically by the
restore command; do not call it explicitly.
Adding actions before and after a restore is required for features of the e environment that require
custom persistency code. Typical cases are when e structs reference external C memory or files. In such
cases, you must explicitly save and recover, or finalize and initialize the data.

Example
The following example uses both pre_restore() and post_restore(). In this example, struct s has an
external pointer that is allocated and freed by C code. If it were not freed before the restore, there would
be memory leaks. If it were not reallocated after the restore, the struct would be inconsistent.
<'
struct s {
allocate_p() is C routine s_allocate_p;
free_p() is C routine s_free_p;
!p: external_pointer;
};
extend sys {
my_s: s;
pre_restore(state_name: string, save_dir: string) is also {
if my_s != NULL {
my_s.free_p();
};
};
post_restore(state_name: string, save_dir: string) is also {
if my_s != NULL {
my_s.allocate_p();
};
};
};
'>

See Also

The pre_save() Method of sys on page 1166

The pre_restore() Method of sys on page 1167

restore in the Specman Command Reference

Specman e Language Reference


1999-2015

1170

Product Version 15.1


All Rights Reserved.

23.2.11 The simulator_save() TCM of Sys


Purpose
Saves the IES simulator and Specman states.

Category
Predefined final TCM for sys

Syntax
sys.simulator_save(snapshot-name:string [, overwrite:bool] [, continue:bool] [, with_log: bool]
[, snapshot-path: string] )
Syntax Example
sys.simulator_save("after_link_train", TRUE, TRUE);

Parameters
snapshot-name

A valid snapshot name.

overwrite: bool

If TRUE, overwrites an existing snapshot with the same name. If FALSE and a
snapshot with that name exists, the snapshot is not saved.
The default is TRUE.

continue: bool

If TRUE, continues the run after saving the snapshot. If FALSE, stops in the
simulator prompt after saving the snapshot.
The default is FALSE.
Note If overwrite is FALSE and the snapshot already exists, the simulator may
stop regardless of the value of continue.

with_log: bool

If TRUE, Specman reads all current log files for the snapshot and saves their contents
in the esv file, as described in Creating a Single Log File for Multiple Simulations, in
Running Specman with Incisive Simulator.
The default is FALSE.

snapshot-path:
string

Specifies the path to the directory where the snapshot is saved. By default, the
snapshot is saved in the work library directory.

Specman e Language Reference


1999-2015

1171
.

Product Version 15.1


All Rights Reserved.

Description
Creates a snapshot of the current simulation state. The snapshot includes both the simulator and
Specman states.
The save takes affect after tick_end, which means that Specman runs until tick_end. Then,control is
passed to the simulator, and the simulator performs the save.
If several calls are done in the same tick, all of them are executed.
Notes

This TCM is supported for IES only. A runtime error is issued if it is used with a third-party simulator.

This TCM is defined as final and, thus, cannot be modified.

Example 1

Using sys.simulator_save()

This example saves the state after the DUT has been initialized and the links trained, but before the start
of the interesting test.
extend USER_DEFINED_TEST_FLOW cdn_uart_virt_seq_s {
!initialization: INIT cdn_uart_seq_s;
!training: LINK_TRAIN cdn_uart_seq_s;
!test_sequence: cdn_uart_seq_s;

body()@driver.clock is {
message(NONE,"Launching USER_DEFINED_TEST_FLOW Virtual Sequence");
do_initialization();
do_link_train();
do_test(); // user defined
}; // body()@driver.c...
do_initialization()@driver.clock is {}; // do_init()@drive...
do_link_train()@driver.clock is {
do training keeping {.driver == driver.cdn_uart_seq_driver;};
sys.simulator_save(after_link_train,TRUE, TRUE);
}; // do_link_train()...
do_test()@driver.clock is {};
}; // extend USER_DEF...

Example 2

sys.simulator_save() File for Inclusion in Regression Runs

You can use simulator_save() in a separate file for inclusion in regression runs only. Following is an
example:
extend USER_DEFINED_TEST_FLOW cdn_uart_virt_seq_s {
do_link_train()@driver.clock is also {
Specman e Language Reference
1999-2015

1172

Product Version 15.1


All Rights Reserved.

sys.simulator_save(after_link_train,TRUE,TRUE);
}; // do_link_train()...

23.2.12 The remap_tick_access() Method of sys


Purpose
Remap path of tick access

Category
Predefined method for sys

Syntax
[sys.]remap_tick_access(name : string) : string
Syntax Example
extend sys {
remap_tick_access(name:string) : string is also {
result = str_replace(name,/top.a.b/,top_a_b);
};
};

Description
You can use the remap_tick_access() method to create customized mapping rules for renaming 'tick'
access HDL paths. This includes access (at run time) and static statements (for example, verilog
variable, and verilog task).
The method receives one parameter, which is the full name of the entity. The name is normalized to use
dots as separators and to delete the leading ~/. The return value of the method is the remapped name.
By default, this method is empty. To implement the hook, you must extend the method to return the
remapped name. For names that should not be remapped, the method can return an empty string.
Notes

The same hooks should be implemented at run time and when writing the stubs file so that the correct
remapped names used inside the stubs file.
Calling the method extensions affects performance, primarily because the extensions generally
involve string matching and regular expressions. Therefore, Cadence recommends that the hook be
used only when other solutions are not available.

Specman e Language Reference


1999-2015

1173
.

Product Version 15.1


All Rights Reserved.

The hook is called for also for internal stub signals. To avoid modifications of them, ensure that you
do not modify any signal names that begin with specman.

Example
In the following example, the Verilog hierarchy defined in the file dut.v is flattened as defined in file
dut_flat.v.
dut.v File
module bottom();
reg[31:0] r1;
endmodule
module middle();
reg[31:0] r1;
bottom b1();
endmodule // middle
module top();
reg[31:0] r1;
middle m1();
initial
$monitor("%t: r1 = %d m1.r1 = %d m1.b1.r1",$time,r1,m1.r1,m1.b1.r1)
endmodule

top.e File
<'
extend sys {
tv : top_verifier is instance;
keep tv.hdl_path() == "~/top";
run() is also {
start tv.my_tcm();
start tv.mv.my_tcm();
start tv.mv.bv.my_tcm();
};
};
unit top_verifier {
mv : middle_verifier is instance;
keep mv.hdl_path() == "m1";
my_tcm()@sys.any is {
wait delay(10);
'r1' = 1;
};
};
unit middle_verifier {
bv : bottom_verifier is instance;

Specman e Language Reference


1999-2015

1174

Product Version 15.1


All Rights Reserved.

keep bv.hdl_path() == "b1";


my_tcm()@sys.any is {
wait delay(20);
'r1' = 1;
};
};
unit bottom_verifier {
my_tcm()@sys.any is {
wait delay(30);
'r1' = 1;
};
};
'>

dut_flat.v File
The flattened DUT is defined in dut_flat.v
module top();
reg[31:0] r1;
reg[31:0] \m1.r1 ;
reg[31:0] \m1.b1.r1 ;
initial
$monitor("%t: r1 = %d \m1.r1 = %d \m1.b1.r1 = ",$time,r1,\m1.r1 ,\m1.b1.r1 );
endmodule

sys Extension with remap_tick_access()


The following e code extends the method remap_tick_access() in top_flat.e so that top_flat.e can
continue to be used without modification.
<'
import top;
extend sys {
remap_tick_access(path:string) : string is also {
if ( path ~ "/top\.(m1.*)/" ) {
result = append("top.\\",$1," ");
};
out("*** Inside remap_tick_access. input = ",path," \
result = ",result); // for debug
};
};
'>

Specman e Language Reference


1999-2015

1175
.

Product Version 15.1


All Rights Reserved.

23.3 Predefined Methods of Any Struct or Unit


Specman has a predefined struct, any_struct, which in turn has many predefined methods. Some of
these predefined methods, such as init() and run(), are invoked automatically when you execute the test
command. Other predefined methods, such as copy() or do_print(), manipulate data within the struct.
All user-defined structs inherit from any_struct, so all its predefined methods are available to any struct
you define.
In addition, there is a predefined generic type any_unit, which is derived from any_struct. any_unit is
the base type implicitly used in user-defined unit types, so predefined methods for any_struct are also
available for any user-defined unit.
The following sections describe the predefined methods that are invoked automatically when you
execute the test command. (See Figure 23-1 on page 1142 for more information on test phases,
commands, and related methods.)

The check() Method of any_struct or any_unit on page 1177

The extract() Method of any_struct or any_unit on page 1183

The finalize() Method of any_struct or any_unit on page 1185

The init() Method of any_struct or any_unit on page 1186

pre_generate() on page 656

post_generate() on page 658

The quit() Method of any_struct or any_unit on page 1189

The run() Method of any_struct or any_unit on page 1192

The following section describe the predefined method that you can use to kill the threads for a struct and
then start it running again:

The rerun() Method of any_struct or any_unit on page 1193

The following sections describe the predefined methods that manipulate data within the struct:

The copy() Method of any_struct or any_unit on page 1178

The get_printed_lines() Method of any_struct or any_unit on page 1180

The do_print() Method of any_struct or any_unit on page 1181

The following section describes the procedural API for temporal operators on even and expect struct
members:

Procedural API for Temporal Operators on event and expect struct Members on page 1197

The following sections describe the predefined methods that you use to manage packing:

Specman e Language Reference


1999-2015

1176

Product Version 15.1


All Rights Reserved.

do_pack() on page 1071

do_unpack() on page 1075

See Also

Unit-Related Predefined Methods for Any Struct on page 307

23.3.1

The check() Method of any_struct or any_unit

Purpose
Check for DUT errors

Category
Predefined method of any struct or unit

Syntax
[exp.]check()
Syntax Example
check() is also {
check that pending == 0
else dut_error("Still have ", pending, " test(s) to do");
};

Parameters
exp

An expression that returns a unit or a struct.

Description
This is an empty method that you can extend for performing post-test checks.
This method is called by global.check_test() when you issue a test or check command from the
Specman command line.

Example
struct track_pending {
Specman e Language Reference
1999-2015

1177
.

Product Version 15.1


All Rights Reserved.

!pending: uint;
more_tests() is {pending += 1;};
fewer_tests() is {pending -= 1;};
check() is also {
check that pending == 0
else dut_error("Still have ", pending, " test(s) to do");
};
};

See Also

The check() Method of sys on page 1164

check that on page 588

check in the Specman Command Reference

23.3.2

The copy() Method of any_struct or any_unit

Purpose
Make a shallow copy

Category
Predefined method of any struct or unit

Syntax
exp.copy(): exp
Syntax Example
var pmv: packet = sys.pmi.copy();

Parameters
exp

An e expression that returns a struct type, scalar type, or string type.

Specman e Language Reference


1999-2015

1178

Product Version 15.1


All Rights Reserved.

Description
Returns a shallow, non-recursive copy of the exp. This means that if the expression is a struct that
contains other lists or structs, the second-level items are not duplicated. Instead, they are copied by
reference.
The following table details how the copy is made, depending on the type of the expression:
scalar

The scalar value is simply assigned as in a normal assignment.

string

The whole string is copied.

struct

If exp is a struct instance, a new struct instance with the same type as the original
struct is allocated. All scalar fields are duplicated. All compound fields (lists or
structs) in the new struct instance point to the corresponding fields in the original
struct.

Notes

Do not use the assignment operator (=) to copy structs into other data objects. The assignment operator
simply manipulates pointers to the data being assigned and does not create new struct instances or lists.
Use the deep_copy() method if you want a recursive copy of a struct that contains compound fields
or items.

Example
<'
struct packet {
header: header;
data[10] :list of byte;
type: [ATM, ETH, IEEE];
};
struct header {
code: uint;
};
extend sys {
pmi: packet;
m() is {
var pmv: packet = sys.pmi.copy();
pmv.data[0] = 0xff;
pmv.header.code = 0xaa;
pmv.type = IEEE;
print pmi.data[0], pmi.header.code, pmi.type;
print pmv.data[0], pmv.header.code, pmv.type;
Specman e Language Reference
1999-2015

1179
.

Product Version 15.1


All Rights Reserved.

};
};
'>

Result
This example shows that any changes in value to lists and structs contained in the copied struct instance
(pmv) are reflected in the original struct instance (pmi) because these items are copied by reference.
cmd-prompt> sys.m()
pmi.data[0] = 0xff
pmi.header.code = 0xaa
pmi.type = ATM
pmv.data[0] = 0xff
pmv.header.code = 0xaa
pmv.type = IEEE

See Also

deep_copy() on page 1458

copy() on page 1356

23.3.3

The get_printed_lines() Method of any_struct or


any_unit

Purpose
Get the printed lines as a list of strings

Category
Predefined method of any struct or unit

Syntax
[exp.]get_printed_lines(): list of string;
Syntax Example
var l: list of string = sys.get_printed_lines();

Specman e Language Reference


1999-2015

1180

Product Version 15.1


All Rights Reserved.

Parameters
exp

An expression that returns a unit or a struct.

Description
When called on a struct or unit instance, this method returns the list of strings representing the lines that
would be printed on screen by the do_print() method for the same instance.
If do_print() is extended for a certain struct or unit type, the result for get_printed_lines() for instances
of that type is affected accordingly. The result of get_printed_lines() is also affected by the current
settings of the print configuration flags, such as -line_size, -radix, etc., in the manner similar to the print
command.

Example
In the following example, calling get_printed_lines() on sys returns the list of lines that will be printed
by the print sys command.
Specman> var l: list of string = sys.get_printed_lines()
Specman> print l
l =
0.
"sys-@1: sys
e_path: sys"
1.
" hdl_path: "
2.
"
------------------------------------------- @sn_dut_error"
3.
"0
!time:
0"
4.
"1
!realtime:
0"
5.
"
------------------------------------------- @sn_message_action"
6.
"2
logger:
message_logger-@2"

See Also

The do_print() Method of any_struct or any_unit on page 1181

23.3.4

The do_print() Method of any_struct or any_unit

Purpose
Print struct info

Specman e Language Reference


1999-2015

1181
.

Product Version 15.1


All Rights Reserved.

Category
Predefined method of any struct or unit

Syntax
[exp.]do_print()
Syntax Example
do_print() is first {
outf("Struct %s :", me.s);
};

Parameters
exp

An expression that returns a unit or a struct.

Description
Controls the printing of information about a particular struct. You can extend this method to customize
the way information is displayed.
This method is called by the print action whenever you print the struct.

Example
<'
struct a {
i: int;
s: string;
do_print() is first {
outf("Struct %s :", me.s);
};
};
extend sys {
m() is {
var aa := a new a with {
.i = 1;
.s = "AA";
};
print aa;
};
};
'>

Specman e Language Reference


1999-2015

1182

Product Version 15.1


All Rights Reserved.

Result
cmd-prompt> sys.m()
aa = Struct AA :a-@0: a
---------------------------------------------@predefined_methods5
0
i:
0x1
1
s:
"AA"

See Also

print in the Specman Command Reference

23.3.5

The extract() Method of any_struct or any_unit

Purpose
Extract DUT information

Category
Predefined method of any struct or unit

Syntax
[exp.]extract()
Syntax Example
extract() is also {
me.flag = 'top.overflow';
print me.flag;
};

Parameters
exp

An expression that returns a unit or a struct.

Description
This method is called before the post-run checking is performed when you issue a check or finalize
command from the Specman command line. (See Figure 23-1 on page 1142 for more information on test
phases.)
Specman e Language Reference
1999-2015

1183
.

Product Version 15.1


All Rights Reserved.

The method is initially empty. You can extend this method to extract data from the DUT before checking
the test results.
This method is called automatically by the global.extract_test() method.

Example
<'
struct packet {
header: header;
data[10] :list of byte;
type: [ATM, ETH, IEEE];
flag: bit;
extract() is also {
me.flag = 'top.overflow';
print me.flag;
};
};
struct header {
code: uint;
};
extend sys {
pmi: packet;
};
'>

Result
cmd-prompt> test
Doing setup ...
Generating the test using seed 0x1...
Starting the test ...
Running the test ...
No actual running requested.
Checking the test ...
me.flag = 0x1
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

The extract() Method of sys on page 1163

extract in the Specman Command Reference

Specman e Language Reference


1999-2015

1184

Product Version 15.1


All Rights Reserved.

23.3.6

The finalize() Method of any_struct or any_unit

Purpose
Finalize test data

Category
Predefined method for any struct or unit

Syntax
[exp.]finalize()
Syntax Example
finalize() is also {
specman("show cover XYZ_router.log");
};

Parameters
exp

An expression that returns a unit or a struct.

Description
The global.finalize_test() method calls the finalize() method of each struct or unit as part of the
post-checking activities, which include writing coverage information. You can also call this method
from the command line with the finalize command.
You can extend the finalize() method of a unit or struct to display or manipulate data.

Example
<'
extend XYZ_router {
finalize() is also {
specman("show cover XYZ_router.log");
};
};
'>

Specman e Language Reference


1999-2015

1185
.

Product Version 15.1


All Rights Reserved.

Results
cmd-prompt> test
Doing setup ...
10 checks were modified.
Generating the test using seed 1...
Starting the test ...
Running the test ...
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

Specman Coverage report


=======================
Command:
Grading_formula:
At least multiplier:
Show mode:
Number of tests:
Note:

show cover -kind = full XYZ_router.log.*


linear
1
both
1
%t is a percent from total, %p is a percent
from parent

Cover group: XYZ_router.log


===========================
"End of package transaction"
....

See Also

finalize in the Specman Command Reference

The finalize() Method of sys on page 1165

23.3.7

The init() Method of any_struct or any_unit

Purpose
Initialize struct

Category
Predefined method of any struct or unit

Specman e Language Reference


1999-2015

1186

Product Version 15.1


All Rights Reserved.

Syntax
[exp.]init()
Syntax Example
init() is also {
is_ok = TRUE;
list_subs = {320; 330; 340; 350; 360};
list_color = {black; red; green; blue; yellow; white};
};

Parameters
exp

An expression that returns a unit or a struct.

Description
The init() method of a struct is called when you create a new instance with a test, start or generate
command (pre-run generation) or with a new, gen or unpack() action (on-the-fly generation). (See
Figure 23-1 on page 1142 for more information on test phases.)
You can extend the init() method of a struct to set values for fields that you want to have a different
value than the default value. By default, all fields of scalar type are initialized to zero. The initial value
of a struct or list is NULL, unless the list is a sized list of scalars, in which case it is initialized to the
proper size with each item set to the default value.
You should consider initializing the non-generated fields of a struct, especially fields of an enumerated
scalar type or unsized lists. Enumerated scalar types are initialized to zero, even if that is not a legal
value for that type. If the field is sampled before it is assigned, you should initialize it. As for lists, if you
intend to fill a list with data from the DUT, you should either size the list or initialize it. Unpacking data
from the DUT into an unsized, uninitialized list causes a runtime error.
If a field is initialized but not marked as non-generated, the initialization is overwritten during
generation. To mark a field as non-generated, place a ! character in front of the field name.

Example
<'
type color: [black, red, green, blue, yellow, white];
type sub_rang1: int [300..500];
struct pm {
!list_color: list of color;
!list_subs: list of sub_rang1;
!is_ok:bool;

Specman e Language Reference


1999-2015

1187
.

Product Version 15.1


All Rights Reserved.

init() is also {
is_ok = TRUE;
list_subs = {320; 330; 340; 350; 360};
list_color = {black; red; green; blue; yellow; white};
};
};
extend sys {
pmi:pm;
};
'>

Result
cmd-prompt> print sys.pmi.list_color, sys.pmi.list_subs,
sys.pmi.is_ok
sys.pmi.list_color =
0.
black
1.
red
2.
green
3.
blue
4.
yellow
5.
white
sys.pmi.list_subs =
0.
320
1.
330
2.
340
3.
350
4.
360
sys.pmi.is_ok = TRUE

See Also

The init() Method of sys on page 1157

generate in the Specman Command Reference

Packing and Unpacking Lists on page 1041

e Data Types on page 137

{... ; ...} on page 113

Specman e Language Reference


1999-2015

1188

Product Version 15.1


All Rights Reserved.

23.3.8

The quit() Method of any_struct or any_unit

Purpose
Kill all threads of a struct or unit instance

Category
Predefined method of any struct or unit

Syntax
[exp.]quit()
Syntax Example
packet.quit();

Parameters
exp

An expression that returns a unit or a struct.

Description
Deactivates a struct instance, killing all threads associated with the struct and enabling garbage
collection. The quit() method emits a quit event for that struct instance at the end of the current tick. At
the end of the current tick, the quit() method kills any TCM threads that were started within the struct in
which the quit() method is called. All attached events and expect members of the struct that are still
running are also killed.
A thread is any started TCM. If a started TCM calls other TCMs, those TCMs are considered subthreads
of the started TCM thread, and the quit() method kills those subthreads, too.
If a struct has more than one started TCM, each TCM runs on a separate, parallel thread. Each thread
shares a unique identifier, or thread handle, with its subthreads. The thread handle is automatically
assigned by the scheduler. You can access threads using the predefined methods of the scheduler.
The quit() method is called by the global.stop_run() method. You can also call it explicitly.

Specman e Language Reference


1999-2015

1189
.

Product Version 15.1


All Rights Reserved.

Example
This example shows the quit() method used in conjunction with the stop_run() routine to stop a run
cleanly. When a packet struct is generated by the inject_packets() method, its TCM monitor() is
also started. The TCM monitor checks the status of the inject_packets() method. Four cycles after the
packet is generated, it is killed by the quit() method. After all packet have been generated and killed,
the stop_run() method is called to stop the simulator.
<'
extend sys {
inject_packets() @sys.any is {
var packet : packet;
for i from 0 to 5 {
wait [1] * cycle;
gen packet;
out("\nInject packet id ", packet.id);
wait [4] * cycle;
packet.quit();
};
stop_run();
};
run() is also {
start inject_packets();
};
};
struct packet {
id : int;
monitor() @sys.any is {
while (TRUE) {
wait [2] * cycle;
out("cycle ", sys.time, " Packet id ", id,
" is still running");
};
};
run() is also {
start monitor();
};
};
'>

Result
cmd-prompt> test
Doing setup ...
Specman e Language Reference
1999-2015

1190

Product Version 15.1


All Rights Reserved.

Generating the test using seed 1...


Starting the test ...
Running the test ...
Inject packet id 134576642
cycle 3 Packet id 134576642 is still running
cycle 5 Packet id 134576642 is still running
Inject packet id -1767441690
cycle 8 Packet id -1767441690 is still running
cycle 10 Packet id -1767441690 is still running
Inject packet id 1480193010
cycle 13 Packet id 1480193010 is still running
cycle 15 Packet id 1480193010 is still running
Inject packet id 370225594
cycle 18 Packet id 370225594 is still running
cycle 20 Packet id 370225594 is still running
Inject packet id 595104854
cycle 23 Packet id 595104854 is still running
cycle 25 Packet id 595104854 is still running
Inject packet id 631871925
cycle 28 Packet id 631871925 is still running
Last specman tick - stop_run() was called
cycle 30 Packet id 631871925 is still running
Normal stop - stop_run() is completed
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

stop_run() on page 902

scheduler.kill() on page 1267

scheduler.terminate_branch() on page 1269

scheduler.terminate_thread() on page 1271

Specman e Language Reference


1999-2015

1191
.

Product Version 15.1


All Rights Reserved.

23.3.9

The run() Method of any_struct or any_unit

Purpose
Recommended place for starting TCMs

Category
Method of any struct or unit

Syntax
[exp.]run()
Syntax Example
run() is also {
start monitor();
};

Parameters
exp

An expression that returns a unit or a struct.

Description
Can be extended to start user-defined TCMs. The method is initially empty.
The run() methods of all structs under sys are called, starting from sys in depth-first field order, by the
global.run_test() method, when you execute a test or a run command.
After this initial pass, when any struct is generated (with the gen action) or allocated (with new), its
run() method is also invoked. This ensures that:

The run() method of each struct instance is called exactly once, thus avoiding multiple instances of
the same started TCM;

TCMs do not start and events do not occur before Specman is ready to accept them;

The run() method is called after generation and uses the generated values.

If you run multiple tests in the same session, the run() method is called once for each test in the session.
The init() method is called only once before the first test.

Specman e Language Reference


1999-2015

1192

Product Version 15.1


All Rights Reserved.

Note
Starting a TCM before the run test phase causes a runtime error. See Load and Start Test Phases and
Predefined Methods on page 1142 for more information on test phases.

Example
<'
struct packet {
id : int;
monitor() @sys.any is {
while (TRUE) {
wait [2] * cycle;
out("cycle ", sys.time,
" Packet id ", id, " is still running");
};
};
run() is also {
start monitor();
};
};
'>

See Also

The run() Method of sys on page 1162

start tcm() on page 537

run in the Specman Command Reference

23.3.10 The rerun() Method of any_struct or any_unit


Purpose
Kill all threads of a struct or unit instance and then call its run() method.

Category
Method of any struct or unit

Specman e Language Reference


1999-2015

1193
.

Product Version 15.1


All Rights Reserved.

Syntax
[instance-exp.]rerun()
Syntax Example
master.rerun();

Parameters
instance-exp

An expression that returns a unit or struct instance.

Description
The rerun() method:
1.

Deactivates a struct or unit instance at the end of the current tick by calling its quit() method. The
quit() method kills any TCM threads, attached events, or expect members that are still running.

2.

Reactivates the struct or unit instance at the beginning of the next cycle (new specman time) by
calling its run() method and activating the attached event and expect members.

Similarly to the quit() method, rerun() is not called recursively for struct sub-structs. If required, you
can extend rerun() to call sub-struct rerun() methods also.
To pause a struct action, first call its quit() method and after the required time call its rerun() method to
reactivate it.

Example
This example suggests how rerun() can be used to verify a DUT reset. In this example, the do_reset()
TCM emulates a reset twice by assigning its reset field to one, waiting for the reset duration, and then
reassigning reset to zero.
Upon instantiation, the device instance activates the events reset_start and reset_end and starts its
monitor() TCM. The events look for changes in the sys.reset field. The monitor() TCM reports the times
when the instance is running.
On the device.reset_start event, the device calls rerun(), which kills the monitor() TCM thread. At the
next tick, device.run() is called again, and the test and monitor() TCM are restarted. Once sys.reset is
assigned to zero, it enters its loop again. The event reset_end occurs, and the device calls
check_register_default_values().
Notice that monitor() does not sync with reset_end because the test might start with sys.reset equal to
zero. In this case you would want monitor() to enter its loop and not wait for a reset fall.

Specman e Language Reference


1999-2015

1194

Product Version 15.1


All Rights Reserved.

<'
extend sys {
device : device is instance;
!reset : uint;
do_reset() @any is {
for i from 1 to 2 {
wait [3];
reset = 1;
wait [10];
reset = 0;
};
wait [3];
stop_run();
};

// 'reset' duration

run() is also {
start do_reset();
};
};
unit device {
event reset_start is rise(sys.reset)@sys.any;
event reset_end is fall(sys.reset)@sys.any;
on reset_start {
out("=== Device saw RESET at ", sys.time, " ===");
rerun();
};
on reset_end {
check_register_default_values();
};
check_register_default_values() is {
out("Device checking registers default values at ",sys.time);
};
monitor()@sys.any is {
sync true(sys.reset == 0);
while (TRUE) {
out("Device is running at ", sys.time );
wait cycle;
};
};

Specman e Language Reference


1999-2015

1195
.

Product Version 15.1


All Rights Reserved.

run() is also{
out("Device run() is called at ", sys.time );
start monitor();
};
};
'>

Results
cmd-prompt> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
Device run() is called at 0
Device is running at 0
Device is running at 1
Device is running at 2
Device is running at 3
=== Device saw RESET at 4 ===
Device is running at 4
Device run() is called at 5
Device checking registers default values at 14
Device is running at 14
Device is running at 15
Device is running at 16
=== Device saw RESET at 17 ===
Device is running at 17
Device run() is called at 18
Device checking registers default values at 27
Device is running at 27
Device is running at 28
Last specman tick - stop_run() was called
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

The quit() Method of any_struct or any_unit on page 1189

The run() Method of any_struct or any_unit on page 1192

run in the Specman Command Reference

Specman e Language Reference


1999-2015

1196

Product Version 15.1


All Rights Reserved.

23.4 Procedural API for Temporal Operators on event


and expect struct Members
This section describes the following methods:

do_abort_on_event() on page 1197


do_stop_on_event() on page 1199
do_start_on_event() on page 1200
do_abort_on_expect() on page 1202
do_stop_on_expect() on page 1204
do_start_on_expect() on page 1205
do_abort_on_struct() on page 1207
do_stop_on_struct() on page 1209
do_start_on_struct() on page 1211
apply_abort_on_struct() on page 1213
apply_stop_on_struct() on page 1215
apply_start_on_struct() on page 1217
do_abort_on_all_events() on page 1219
do_stop_on_all_events() on page 1219
do_start_on_all_events() on page 1219
do_abort_on_all_expects() on page 1219
do_stop_on_all_expects() on page 1219
do_start_on_all_expects() on page 1219
do_abort_on_subtree() on page 1219
do_stop_on_subtree() on page 1221
do_start_on_subtree() on page 1223
propagate_abort_on_subtree() on page 1225
propagate_stop_on_subtree() on page 1227
propagate_start_on_subtree() on page 1229
do_abort_on_all_instance_fields() on page 1231
do_stop_on_all_instance_fields() on page 1231
do_start_on_all_instance_fields() on page 1232

23.4.1

do_abort_on_event()

Purpose
Apply the abort operator on the event struct member

Category
Predefined method of any struct or unit
Specman e Language Reference
1999-2015

1197
.

Product Version 15.1


All Rights Reserved.

Syntax
do_abort_on_event(name: string, force: bool);

Description
This method immediately applies the abort operator on the event name of the target struct, if attributed
operators of the event name and force parameters allow it:

If force is FALSE, the event name is affected only if no abort operator is attributed to it, or its condition
is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
extend sys {
event a;
event b;
event checker is @a => not @b;
on checker {
out("Checked condition happened");
};
run() is also {
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("aborting the event, it will not fire");
do_abort_on_event("checker", FALSE);
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting of b, event will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>
Specman e Language Reference
1999-2015

1198

Product Version 15.1


All Rights Reserved.

Result
emitting a
wait [1]
aborting the event, it will not fire
wait [1]
emitting a
wait [1]
no emitting of b, event will fire
wait [1]
Checked condition happened

23.4.2

do_stop_on_event()

Purpose
Apply the stop operator on the event struct member

Category
Predefined method of any struct or unit

Syntax
do_stop_on_event(name: string, force: bool);

Description
This method immediately applies the stop operator on the event name of the target struct, if attributed
operators of the event name and force parameters allow it:

If force is FALSE, the event name is affected only if no abort operator is attributed to it, or its
condition is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
extend sys {
event a;
event b;
Specman e Language Reference
1999-2015

1199
.

Product Version 15.1


All Rights Reserved.

event checker is @a => not @b;


on checker {
out("Checked condition happened");
};
run() is also {
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event will fire");
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
out("stopping the event, it will not fire");
do_stop_on_event("checker", FALSE);
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
no emitting, event will fire
wait [1]
Checked condition happened
emitting a
wait [1]
stopping the event, it will not fire
wait [1]

23.4.3

do_start_on_event()

Purpose
Apply the start operator on the event struct member
Specman e Language Reference
1999-2015

1200

Product Version 15.1


All Rights Reserved.

Category
Predefined method of any struct or unit

Syntax
do_start_on_event(name: string, force: bool);

Description
This method immediately applies the start operator on the event name of the target struct, if attributed
operators of the event name and force parameters allow it:

If force is FALSE, the event name is affected only if no abort operator is attributed to it, or its
condition is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
extend sys {
event a;
event b;
event checker is @a => not @b;
on checker {
out("Checked condition happened");
};
run() is also {
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("stopping the event, it will not fire");
do_stop_on_event("checker", FALSE);
out("wait [1]");
wait [1];
out("starting the event");
do_start_on_event("checker", FALSE);
out("emitting a");
emit a;
out("wait [1]");
wait [1];
Specman e Language Reference
1999-2015

1201
.

Product Version 15.1


All Rights Reserved.

out("no emitting, event will fire");


out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
stopping the event, it will not fire
wait [1]
starting the event
emitting a
wait [1]
no emitting, event will fire
wait [1]
Checked condition happened

23.4.4

do_abort_on_expect()

Purpose
Apply the abort operator on the expect struct member

Category
Predefined method of any struct or unit

Syntax
do_abort_on_event(name: string, force: bool);

Description
This method immediately applies the abort operator on the expect name of the target struct, if attributed
operators of the expect name and force parameters allow it:

If force is FALSE, the expect name is affected only if no abort operator is attributed to it, or its
condition is none; condition @event-name or empty disables the method.

Specman e Language Reference


1999-2015

1202

Product Version 15.1


All Rights Reserved.

If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
extend sys {
event a;
event b;
expect checker is @a => @b;
run() is also {
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("aborting the expect, it will not fire");
do_abort_on_expect("checker", FALSE);
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting of b, expect will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
aborting the expect, it will not fire
wait [1]
emitting a
wait [1]
no emitting of b, expect will fire
wait [1]
------------------------------------------------------*** Dut error at time 3
In sys-@1 (unit: sys):
Specman e Language Reference
1999-2015

1203
.

Product Version 15.1


All Rights Reserved.

checker: Expect failed.


-------------------------------------------------------

23.4.5

do_stop_on_expect()

Purpose
Apply the stop operator on the expect struct member

Category
Predefined method of any struct or unit

Syntax
do_stop_on_expect(name: string, force: bool);

Description
This method immediately applies the stop operator on the expect name of the target struct, if attributed
operators of the expect name and force parameters allow it:

If force is FALSE, the expect name is affected only if no abort operator is attributed to it, or its
condition is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
extend sys {
event a;
event b;
expect checker is @a => @b;
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
Specman e Language Reference
1999-2015

1204

Product Version 15.1


All Rights Reserved.

wait [1];
out("no emitting, expect will fire");
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
out("stopping the expect, it will not fire");
do_stop_on_expect("checker", FALSE);
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
no emitting, expect will fire
wait [1]
------------------------------------------------------*** Dut warning at time 1
In sys-@1 (unit: sys):
checker: Expect failed.
------------------------------------------------------emitting a
wait [1]
stopping the event, it will not fire
wait [1]

23.4.6

do_start_on_expect()

Purpose
Apply the start operator on the expect struct member

Category
Predefined method of any struct or unit
Specman e Language Reference
1999-2015

1205
.

Product Version 15.1


All Rights Reserved.

Syntax
do_start_on_expect(name: string, force: bool);

Description
This method immediately applies the start operator on the expect name of the target struct, if attributed
operators of the expect name and force parameters allow it:

If force is FALSE, the expect name is affected only if no abort operator is attributed to it, or its
condition is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
extend sys {
event a;
event b;
expect checker is @a => @b;
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("stopping the expect, it will not fire");
do_stop_on_expect("checker", FALSE);
out("wait [1]");
wait [1];
out("starting the expect");
do_start_on_expect("checker", FALSE);
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>
Specman e Language Reference
1999-2015

1206

Product Version 15.1


All Rights Reserved.

Result
emitting a
wait [1]
stopping the expect, it will not fire
wait [1]
starting the expect
emitting a
wait [1]
no emitting, event will fire
wait [1]
------------------------------------------------------*** Dut warning at time 3
In sys-@1 (unit: sys):
checker: Expect failed.
-------------------------------------------------------

23.4.7

do_abort_on_struct()

Purpose
Apply the abort operator on events and expects of a struct.
By default it applies it on all of them, but can be customized by extending the apply_abort_on_struct()
method.

Category
Predefined method of any struct or unit

Syntax
do_abort_on_struct(force: bool);

Description
This method immediately applies the abort operator on events and expects of the target struct, if
attributed operators of events and expects and force parameter allow it:

Specman e Language Reference


1999-2015

1207
.

Product Version 15.1


All Rights Reserved.

If force is FALSE, the event name is affected only if no abort operator is attributed to it, or its
condition is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
extend sys {
event a;
event b;
event checker_event is @a => not @b;
on checker_event {
out("Checked condition happened");
};
expect checker_expect is @a => @b;
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("aborting, event and expect will not fire");
do_abort_on_struct(FALSE);
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting of b, event and expect will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
aborting, event and expect will not fire
wait [1]

Specman e Language Reference


1999-2015

1208

Product Version 15.1


All Rights Reserved.

emitting a
wait [1]
no emitting of b, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 3
In sys-@1 (unit: sys):
checker_expect: Expect failed.
-------------------------------------------------------

23.4.8

do_stop_on_struct()

Purpose
Apply the stop operator on events and expects of a struct.
By default it applies it on all of them, but it can be customized by extending the apply_stop_on_struct()
method.

Category
Predefined method of any struct or unit

Syntax
do_stop_on_struct(force: bool);

Description
This method immediately applies the stop operator on events and expects of the target struct, if
attributed operators of events and expects and the force parameter allow it:

If force is FALSE, the event name is affected only if no stop operator is attributed to it, or its condition
is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
Specman e Language Reference
1999-2015

1209
.

Product Version 15.1


All Rights Reserved.

extend sys {
event a;
event b;
event checker_event is @a => not @b;
on checker_event {
out("Checked condition happened");
};
expect checker_expect is @a => @b;
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event and expect will fire");
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
out("stopping, event and expect will not fire");
do_stop_on_struct(FALSE);
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
no emitting, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 1
In sys-@1 (unit: sys):
checker_expect: Expect failed.
-------------------------------------------------------

Specman e Language Reference


1999-2015

1210

Product Version 15.1


All Rights Reserved.

emitting a
wait [1]
stopping, event and expect will not fire
wait [1]

23.4.9

do_start_on_struct()

Purpose
Apply the start operator on events and expects of a struct.
By default it applies it on all of them, but it can be customized by extending the apply_start_on_struct()
method.

Category
Predefined method of any struct or unit

Syntax
do_start_on_struct(force: bool);

Description
This method immediately applies the start operator on events and expects of the target struct, if
attributed operators of events and expects and the force parameter allow it:

If force is FALSE, the event name is affected only if no start operator is attributed to it, or its condition
is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
extend sys {
event a;
event b;
event checker is @a => not @b;
on checker {
out("Checked condition happened");
};
Specman e Language Reference
1999-2015

1211
.

Product Version 15.1


All Rights Reserved.

expect checker is @a => @b;


run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("stopping, event and expect will not fire");
do_stop_on_struct( FALSE);
out("wait [1]");
wait [1];
out("starting");
do_start_on_struct(FALSE);
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event and expect will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
stopping, event and expect will not fire
wait [1]
starting
emitting a
wait [1]
no emitting, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 3
In sys-@1 (unit: sys):
checker: Expect failed.

Specman e Language Reference


1999-2015

1212

Product Version 15.1


All Rights Reserved.

-------------------------------------------------------

23.4.10 apply_abort_on_struct()
Purpose
Customize how the abort operator is applied on temporal struct members of a struct

Category
Predefined method of any struct or unit

Syntax
apply_abort_on_struct(force: bool);

Description
To customize how the abort operator is applied on temporal struct members, extend this method for the
specific struct. The default implementation of the method contains two calls:

do_abort_on_all_events(force);
do_abort_on_all_expects(force);

do_abort_on_all_events() and do_abort_on_all_expects() are predefined methods, which actually


apply the call on the temporal struct members. They can be used for customization. However it is
recommended NOT to extend the API do_* methods, or call apply_* methods instead of API do_*
methods.

Example
<'
extend sys {
apply_abort_on_struct(force: bool) is only {
out("aborting expects");
do_abort_on_all_expects(force);
out("events not aborted!");
};
event a;
event b;
event checker_event is @a => not @b;
on checker_event {
Specman e Language Reference
1999-2015

1213
.

Product Version 15.1


All Rights Reserved.

out("Checked condition happened");


};
expect checker_expect is @a => @b;
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("aborting, event and expect should not fire");
do_abort_on_struct(FALSE);
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting of b, event and expect will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
aborting, event and expect should not fire
aborting expects
events not aborted!
wait [1]
Checked condition happened
emitting a
wait [1]
no emitting of b, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 3
In sys-@1 (unit: sys):

Specman e Language Reference


1999-2015

1214

Product Version 15.1


All Rights Reserved.

checker_expect: Expect failed.


-------------------------------------------------------

23.4.11 apply_stop_on_struct()
Purpose
Customize how the stop operator is applied on temporal struct members of a struct

Category
Predefined method of any struct or unit

Syntax
apply_abort_on_struct(force: bool);

Description
To customize how the stop operator is applied on temporal struct members, extend this method for the
specific struct. The default implementation of the method contains two calls:

do_stop_on_all_events(force);
do_stop_on_all_expects(force);

do_stop_on_all_events() and do_stop_on_all_expects() are predefined methods, which actually apply


the call on the temporal struct members. They can be used for customization. However it is
recommended NOT to extend API do_* methods, or call apply_* methods instead of API do_*
methods.

Example
<'
extend sys {
apply_stop_on_struct(force: bool) is only {
out("stoping expects");
do_stop_on_all_expects(force);
out("events not stoped!");
};
event a;
event b;
Specman e Language Reference
1999-2015

1215
.

Product Version 15.1


All Rights Reserved.

event checker_event is @a => not @b;


on checker_event {
out("Checked condition happened");
};
expect checker_expect is @a => @b;
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event and expect will fire");
out("wait [1]");
wait [1];
out("wait [1]");
wait [1];
out("stopping, event and expect should not fire");
do_stop_on_struct(FALSE);
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
no emitting, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 1
In sys-@1 (unit: sys):
checker_expect: Expect failed.
------------------------------------------------------wait [1]
Checked condition happened
stopping, event and expect should not fire
stopping expects

Specman e Language Reference


1999-2015

1216

Product Version 15.1


All Rights Reserved.

events not stopped!


wait [1]
Checked condition happened

23.4.12 apply_start_on_struct()
Purpose
Customize how the start operator is applied on temporal struct members of a struct

Category
Predefined method of any struct or unit

Syntax
apply_start_on_struct(force: bool);

Description
To customize how the start operator is applied on temporal struct members, extend this method for the
specific struct. The default implementation of the method contains two calls:

do_start_on_all_events(force);
do_start_on_all_expects(force);

do_start_on_all_events() and do_start_on_all_expects() are predefined methods, which actually


apply the call on the temporal struct members. They can be used for customization. However it is
recommended NOT to extend API do_* methods, or call apply_* methods instead of API do_*
methods.

Example
<'
extend sys {
apply_start_on_struct(force: bool) is only {
out("starting expects");
do_start_on_all_expects(force);
out("events not started!");
};
event a;
event b;
Specman e Language Reference
1999-2015

1217
.

Product Version 15.1


All Rights Reserved.

event checker is @a => not @b;


on checker {
out("Checked condition happened");
};
expect checker is @a => @b;
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("stopping, event and expect will not fire");
do_stop_on_struct( FALSE);
out("wait [1]");
wait [1];
out("starting");
do_start_on_struct(FALSE);
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event and expect should fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
stopping, event and expect will not fire
wait [1]
starting
starting expects
events not started!
emitting a
wait [1]
no emitting, event and expect should fire
wait [1]
-------------------------------------------------------

Specman e Language Reference


1999-2015

1218

Product Version 15.1


All Rights Reserved.

*** Dut warning at time 3


In sys-@1 (unit: sys):
checker: Expect failed.
-------------------------------------------------------

23.4.13 do_abort_on_all_events()
See apply_abort_on_struct() on page 1213.

23.4.14 do_stop_on_all_events()
See apply_stop_on_struct() on page 1215.

23.4.15 do_start_on_all_events()
See apply_start_on_struct() on page 1217.

23.4.16 do_abort_on_all_expects()
See apply_abort_on_struct() on page 1213.

23.4.17 do_stop_on_all_expects()
See apply_stop_on_struct() on page 1215.

23.4.18 do_start_on_all_expects()
See apply_start_on_struct() on page 1217.

23.4.19 do_abort_on_subtree()
Apply the abort operator on specified unit and propagate to the unit sub-tree under it

Specman e Language Reference


1999-2015

1219
.

Product Version 15.1


All Rights Reserved.

Category
Predefined method of any unit

Syntax
do_abort_on_subtree(force: bool);

Description
This method immediately applies the abort operator on events and expects of the target unit and unit
sub-tree under it, if attributed operators of events and expects and the force parameter allow it:

If force is FALSE, the event name is affected only if no abort operator is attributed to it, or its
condition is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
unit u {
expect checker_expect is @sys.a => @sys.b;
};
extend sys {
u: u is instance;
event a;
event b;
event checker_event is @a => not @b;
on checker_event {
out("Checked condition happened");
};
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("aborting, event and expect will not fire");
do_abort_on_subtree(FALSE);
out("wait [1]");
wait [1];
out("emitting a");
Specman e Language Reference
1999-2015

1220

Product Version 15.1


All Rights Reserved.

emit a;
out("wait [1]");
wait [1];
out("no emitting of b, event and expect will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
aborting, event and expect will not fire
wait [1]
emitting a
wait [1]
no emitting of b, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 3
In u-@1 (unit: sys.u):
checker_expect: Expect failed.
-------------------------------------------------------

23.4.20 do_stop_on_subtree()
Apply the stop operator on the specified unit and propagate it to the unit sub-tree under it

Category
Predefined method of any unit

Syntax
do_stop_on_subtree(force: bool);

Specman e Language Reference


1999-2015

1221
.

Product Version 15.1


All Rights Reserved.

Description
This method immediately applies the stop operator on events and expects of the target unit and the unit
sub-tree under it, if attributed operators of events and expects and the force parameter allow it:

If force is FALSE, the event name is affected only if no stop operator is attributed to it, or its condition
is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Example
<'
unit u {
expect checker_expect is @sys.a => @sys.b;
};
extend sys {
u: u is instance;
event a;
event b;
event checker_event is @a => not @b;
on checker_event {
out("Checked condition happened");
};
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event and expect will fire");
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
out("stopping, event and expect will not fire");
do_stop_on_subtree(FALSE);
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Specman e Language Reference


1999-2015

1222

Product Version 15.1


All Rights Reserved.

Result
emitting a
wait [1]
no emitting, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 1
In u-@1 (unit: sys.u):
checker_expect: Expect failed.
------------------------------------------------------emitting a
wait [1]
stopping, event and expect will not fire
wait [1]

23.4.21 do_start_on_subtree()
Apply the start operator on the specified unit and propagate it to the unit sub-tree under it

Category
Predefined method of any unit

Syntax
do_start_on_subtree(force: bool)

Description
This method immediately applies the start operator on events and expects of the target unit and the unit
sub-tree under it, if attributed operators of events and expects and the force parameter allow it:

If force is FALSE, the event name is affected only if no start operator is attributed to it, or its condition
is none; condition @event-name or empty disables the method.
If force is TRUE, the temporal struct member is affected regardless attributed operators.

Specman e Language Reference


1999-2015

1223
.

Product Version 15.1


All Rights Reserved.

Example
<'
unit u {
expect checker_expect is @sys.a => @sys.b;
};
extend sys {
u: u is instance;
event a;
event b;
event checker is @a => not @b;
on checker {
out("Checked condition happened");
};
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("stopping, event and expect will not fire");
do_stop_on_subtree( FALSE);
out("wait [1]");
wait [1];
out("starting");
do_start_on_subtree(FALSE);
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event and expect will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
stopping, event and expect will not fire
wait [1]
starting
Specman e Language Reference
1999-2015

1224

Product Version 15.1


All Rights Reserved.

emitting a
wait [1]
no emitting, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 3
In u-@1 (unit: sys.u):
checker_expect: Expect failed.
-------------------------------------------------------

23.4.22 propagate_abort_on_subtree()
Purpose
Customize how the abort operator is propagated on temporal struct members of a specified unit and the
unit sub-tree under it

Category
Predefined method of any unit

Syntax
propagate_abort_on_subtree(force: bool)

Description
To customize how the abort operator is propagated on temporal struct members of a specified unit and
the unit sub-tree under it, extend this method for the specific struct. The default implementation of the
method contains two calls:

do_abort_on_struct(force);
do_abort_on_all_instance_fields(force);

do_abort_on_struct() and do_abort_on_all_instance_fields() are predefined methods, which actually


propagate the call on the temporal struct members of the unit and the sub-tree. They can be used for
customization. However it is recommended NOT to extend the API do_* methods, or call propagate_*
methods instead of the API do_* methods.

Specman e Language Reference


1999-2015

1225
.

Product Version 15.1


All Rights Reserved.

Example
<'
unit u {
expect checker_expect is @sys.a => @sys.b;
};
extend sys {
propagate_abort_on_subtree(force: bool) is only {
out("propagating on instance fields");
do_abort_on_all_instance_fields(force);
out("no propagation on the unit itself!");
};
u: u is instance;
event a;
event b;
event checker_event is @a => not @b;
on checker_event {
out("Checked condition happened");
};
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("aborting, event and expect should not fire");
do_abort_on_subtree(FALSE);
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting of b, event and expect will fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
Specman e Language Reference
1999-2015

1226

Product Version 15.1


All Rights Reserved.

aborting, event and expect should not fire


propagating on instance fields
no propagation on the unit itself!
wait [1]
Checked condition happened
emitting a
wait [1]
no emitting of b, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 3
In u-@1 (unit: sys.u):
checker_expect: Expect failed.
-------------------------------------------------------

23.4.23 propagate_stop_on_subtree()
Purpose
Customize how the stop operator is propagated on temporal struct members of a specified unit and the
unit sub-tree under it

Category
Predefined method of any unit

Syntax
propagate_stop_on_subtree(force: bool)

Description
To customize how the stop operator is propagated on temporal struct members of a specified unit and the
unit sub-tree under it, extend this method for the specific struct. The default implementation of the
method contains two calls:

do_stop_on_struct(force);
do_stop_on_all_instance_fields(force);

Specman e Language Reference


1999-2015

1227
.

Product Version 15.1


All Rights Reserved.

do_stop_on_struct() and do_stop_on_all_instance_fields() are predefined methods, which actually


propagate the call on the temporal struct members of the unit and the sub-tree. They can be used for
customization. However it is recommended NOT to extend the API do_* methods, or call propagate_*
methods instead of API do_* methods.

Example
<'
unit u {
expect checker_expect is @sys.a => @sys.b;
};
extend sys {
propagate_stop_on_subtree(force: bool) is only {
out("propagating on instance fields");
do_stop_on_all_instance_fields(force);
out("no propagation on the unit itself!");
};
u: u is instance;
event a;
event b;
event checker_event is @a => not @b;
on checker_event {
out("Checked condition happened");
};
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event and expect will fire");
out("wait [1]");
wait [1];
out("emitting a");
emit a;
out("wait [1]");
out("stopping, event and expect should not fire");
do_stop_on_subtree(FALSE);
out("wait [2]");
wait [2];
stop_run();
};
};
'>
Specman e Language Reference
1999-2015

1228

Product Version 15.1


All Rights Reserved.

Result
emitting a
wait [1]
no emitting, event and expect will fire
wait [1]
Checked condition happened
------------------------------------------------------*** Dut warning at time 1
In u-@1 (unit: sys.u):
checker_expect: Expect failed.
------------------------------------------------------emitting a
wait [1]
stopping, event and expect should not fire
propagating on instance fields
no propagation on the unit itself!
wait [2]
Checked condition happened

23.4.24 propagate_start_on_subtree()
Purpose
Customize how the start operator is propagated on temporal struct members of a specified unit and the
unit sub-tree under it

Category
Predefined method of any unit

Syntax
propagate_start_on_subtree(force: bool)

Specman e Language Reference


1999-2015

1229
.

Product Version 15.1


All Rights Reserved.

Description
To customize how the start operator is propagated on temporal struct members of a specified unit and
unit sub-tree under it, extend this method for the specific struct. The default implementation of the
method contains two calls:

do_start_on_struct(force);
do_start_on_all_instance_fields(force);

do_start_on_struct() and do_start_on_all_instance_fields() are predefined methods, which actually


propagate the call on the temporal struct members of the unit and the sub-tree. They can be used for
customization. However it is recommended NOT to extend the API do_* methods, or call propagate_*
methods instead of API do_* methods.

Example
<'
unit u {
expect checker_expect is @sys.a => @sys.b;
};
extend sys {
propagate_start_on_subtree(force: bool) is only {
out("propagating on instance fields");
do_start_on_all_instance_fields(force);
out("no propagation on the unit itself!");
};
u: u is instance;
event a;
event b;
event checker_event is @a => not @b;
on checker_event {
out("Checked condition happened");
};
run() is also {
set_check("......", WARNING);
start emitter();
};
emitter()@any is {
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("stopping, event and expect will not fire");
do_stop_on_subtree( FALSE);
out("wait [1]");
wait [1];
out("starting");
Specman e Language Reference
1999-2015

1230

Product Version 15.1


All Rights Reserved.

do_start_on_subtree(FALSE);
out("emitting a");
emit a;
out("wait [1]");
wait [1];
out("no emitting, event and expect should fire");
out("wait [1]");
wait [1];
stop_run();
};
};
'>

Result
emitting a
wait [1]
stopping, event and expect will not fire
wait [1]
starting
propagating on instance fields
no propagation on the unit itself!
emitting a
wait [1]
no emitting, event and expect will fire
wait [1]
------------------------------------------------------*** Dut warning at time 3
In u-@1 (unit: sys.u):
checker_expect: Expect failed.
-------------------------------------------------------

23.4.25 do_abort_on_all_instance_fields()
See propagate_abort_on_subtree() on page 1225.

23.4.26 do_stop_on_all_instance_fields()
See propagate_stop_on_subtree() on page 1227.

Specman e Language Reference


1999-2015

1231
.

Product Version 15.1


All Rights Reserved.

23.4.27 do_start_on_all_instance_fields()
See propagate_start_on_subtree() on page 1229.

23.5 Coverage Methods


The covers struct is a predefined struct containing methods that you use for coverage and coverage
grading. With the exception of the set_external_cover() and write_cover_file() methods, all of these
methods are methods of the covers struct.

covers.include_tests() on page 1233

covers.set_weight() on page 1234

covers.set_at_least() on page 1236

covers.set_cover() on page 1237

covers.set_cover_block() on page 1240

covers.set_cover_check() on page 1241

covers.set_per_inst_for_struct() on page 1243

covers.get_contributing_runs() on page 1245

covers.get_unique_buckets() on page 1246

covers.write_cover_file() on page 1248

covers.compute_overall_grade() on page 1249

covers.get_overall_grade() on page 1251

covers.get_ucd_path() on page 1252

covers.get_test_name() on page 1253

covers.get_seed() on page 1255

covers.set_unicov_hier() on page 1256

covers.set_cross_instance_collection() on page 1258

covers.get_top_size_items() on page 1259

See Also
The following section describes another predefined method you use for coverage:

set_check() on page 599

Specman e Language Reference


1999-2015

1232

Product Version 15.1


All Rights Reserved.

23.5.1

covers.include_tests()

Purpose
Specify which test runs coverage information will be displayed for.

Category
Predefined method of the predefined struct global.covers

Syntax
covers.include_tests(full-run-name: string, bool: exp)
Syntax Example
covers.include_tests("tests_A:run_A_10", TRUE);

Parameters
full-run-name

The name of the test to include or exclude.

bool-exp

Set to TRUE to include the specified test, FALSE to exclude it.


After the read cover command has been executed, all tests are
included.

Description
The show coverage command displays coverage data for a test or series of tests. This method allows
you to specify which test runs you want to see coverage information for. It also determines which test
runs will be included in the Show Coverage GUI and by the Coverage API.
If you are reading in .ucd files to load coverage information, this method should be called only after
the .ucd files have been read.

Example
The following example shows several ways to specify test runs for display by show coverage.
<'
extend sys {
setup() is also {
covers.include_tests("tests_A:...", FALSE);
Specman e Language Reference
1999-2015

1233
.

Product Version 15.1


All Rights Reserved.

covers.include_tests("...crc_test", TRUE);
covers.include_tests("/.*crc_test.*/", TRUE);
};
};
'>

See Also

show cover in the Specman Command Reference

23.5.2

covers.set_weight()

Purpose
Specify the coverage grading weight of a group or item

Category
Predefined method of the predefined struct global.covers

Syntax
covers.set_weight(entity-names: string, value: int, bool: exp)
Syntax Example
covers.set_weight("inst.done", 4, FALSE);

Parameters
entity-names

A string of the form struct-name.group-name.item-name, where group-name is:


event-name[(instance-name)]
and where instance-name is one of the following:
per_type
item-name == bucket-name (for item instance sub-groups)
e-path-exp (for cover group instances)
and where e-path-exp has the following form:

e_path==sys.unit-inst[....]
Note

Wildcards are allowed.

Specman e Language Reference


1999-2015

1234

Product Version 15.1


All Rights Reserved.

value

The integer weight value to set.

bool

When this is FALSE, it changes the weights of all matching groups or items to value.
When this is TRUE, the weights of all matching groups or items are multiplied by value.

Description
Coverage grading uses weights to emphasize the affect of particular groups or items relative to others.
The weights can be specified in the coverage group or item definitions. This method sets the weights
procedurally. It overrides the weights set in the group or item definitions. Weights can be set explicitly,
or can be multiplied by a given value.
If you are reading in .ucd files to load coverage information, this method should be called only after
the .ucd files have been read.

Example
The following example shows several ways to set coverage grading weights.
<'
extend sys {
pre_generate() is also {
// change the weight of done group to 4:
covers.set_weight("inst.done", 4, FALSE);
// multiply the len item weight by 5:
covers.set_weight("inst.done.len", 5, TRUE);
// set the weight of all groups in intrp to 0:
covers.set_weight("intrp.*", 0, FALSE);
// multiply by 3 the weights of items that start with cross:
covers.set_weight("inst.done.cross*", 3, TRUE);
};
};
'>

See Also

Grading Coverage in Managing Coverage for e Testbenches

cover on page 735

item on page 746

covers.set_at_least() on page 1236

Specman e Language Reference


1999-2015

1235
.

Product Version 15.1


All Rights Reserved.

23.5.3

covers.set_at_least()

Purpose
Set the minimum number of samples needed to fill a bucket

Category
Predefined method of the predefined struct global.covers

Syntax
covers.set_at_least(entity-names: string, value: int, exp: bool)
Syntax Example
covers.set_at_least("inst.done", 4, FALSE);

Parameters
entity-names

A string of the form struct-name.group-name.item-name, where group-name is:


event-name[(instance-name)]
and where instance-name is one of the following:
per_type
item-name == bucket-name (for item instance sub-groups)
e-path-exp (for cover group instances)
and where e-path-exp has the following form:

e_path==sys.unit-inst[....]
Note

Wildcards are allowed.

value

The at-least integer value to set.

bool

When this is FALSE, it sets the at-least number for all matching items to value.
When this is TRUE, it multiplies the at-least number for all matching items by value.

Specman e Language Reference


1999-2015

1236

Product Version 15.1


All Rights Reserved.

Description
The minimum number of samples required to fill a bucket can be set in the coverage group or item
definitions. This method can be used to set the number procedurally. It overrides the numbers set in the
group or item definitions.
If the entity-name is a coverage group name, all items in the group are affected. If the entity-name
matches items within a coverage group, only those items are affected.
If you are reading in .ucd files to load coverage information, this method should be called only after
the .ucd files have been read.

Example
The following example shows several ways to set coverage at-least numbers.
<'
extend sys {
pre_generate() is also {
// set at-least to 4 for all for done group items:
covers.set_at_least("inst.done", 4, FALSE);
// multiply at-least by 4 for the len item:
covers.set_at_least("inst.done.len", 5, TRUE);
// set at-least to 1 for all items in the intrp struct:
covers.set_at_least("intrp.*", 1, FALSE);
// multiply at-least by 3 for items that start with cross:
covers.set_at_least("inst.done.cross*", 3, TRUE);
};
};
'>

See Also

Specifying Buckets in Managing Coverage for e Testbenches

Making Ungradable Items Gradable in Managing Coverage for e Testbenches

cover on page 735

item on page 746

23.5.4

covers.set_cover()

Purpose
Turns coverage data collection and display on or off for specified items or events
Specman e Language Reference
1999-2015

1237
.

Product Version 15.1


All Rights Reserved.

Category
Predefined method of the predefined struct global.covers

Syntax
covers.set_cover(entity-names|events: string, bool: exp)
Syntax Example
covers.set_cover("packet.*", FALSE);

Parameters
entity-names A string of the form struct-name.group-name.item-name, where group-name is:
event-name[(instance-name)]
and where instance-name is one of the following:
per_type
item-name == bucket-name (for item instance sub-groups)
e-path-exp (for cover group instances)
and where e-path-exp has the following form:

e_path==sys.unit-inst[....]
Note
event

Wildcards are allowed.

A string, enclosed in double quotes, specifying the event you want to turn on or off. This may
include wild cards.
Enter the name of the event using the following syntax:
session.events.struct_type__event_name
where the struct type and the event name are separated by two underscores. Wild cards may
be used.
If you enter only one name, it is treated as a struct type, and the method affects all events in
that struct type.

bool

Set to TRUE to turn on coverage for the item or FALSE to turn coverage off.

Specman e Language Reference


1999-2015

1238

Product Version 15.1


All Rights Reserved.

Description
By default, coverage data is collected for all defined coverage items and groups, and for all user-defined
events. This method selectively turns data collection on or off for specified items, groups, or events.
After coverage data has been collected and written by a test or set of tests, this method can be used to
selectively turn on or off the display of the coverage data for specified items, groups, or events, by the
show cover command.
Although this method can be used to filter samples during periods in which they are not valid, for
performance reasons, filtering should be done using when subtypes instead.
Additionally, if the test ends while coverage collection is turned off by set_cover() for one or more
coverage groups, then set_cover() must be called again to re-enable sampling before the .ucd file is
written, in order to include the previously collected samples for those groups in the .ucd file.

Example 1
The following example turns off coverage data collection for all items in all coverage groups defined in
the inst struct, and then turns back on the collection of data for the len item in the done group in
that struct.
<'
extend sys {
setup() is also {
covers.set_cover("inst.*.*", FALSE);
covers.set_cover("inst.done.len", TRUE);
};
};
'>

Example 2
The following example turns off coverage data collection for an event named my_event defined in the
inst struct.
<'
extend sys {
setup() is also {
covers.set_cover("session.events.inst__my_event", FALSE);
};
};
'>

Example 3
The following example turns off coverage data collection for all events in the struct named my_struct:.
Specman e Language Reference
1999-2015

1239
.

Product Version 15.1


All Rights Reserved.

<'
extend sys {
setup() is also {
covers.set_cover("my_struct", FALSE);
};
};
'>

See Also

About Test Coverage in Managing Coverage for e Testbenches

show cover in the Specman Command Reference

23.5.5

covers.set_cover_block()

Purpose
Disables or enables coverage data collection for specified modules or files

Category
Predefined method of the predefined struct global.covers

Syntax
covers.set_cover_block(module-wc: string, enable: bool)
Syntax Example

covers.set_cover_block("*_bc", TRUE);

Parameters
module-wc

A wildcard string that specifies all modules, or all modules in the specified files, to enable
or disable at load time for block coverage data collection.

enable

If TRUE, block coverage data collection is enabled for all affected modules, or disabled
if FALSE.

Specman e Language Reference


1999-2015

1240

Product Version 15.1


All Rights Reserved.

Description
The block_coverage_mode option to the configure coverage command controls whether block
coverage data is collected for modules in a given file. You can use the set_cover_block() method to
specify which modules to enable or disable within the group of modules enabled by the
block_coverage_mode option.
This method affects only modules that were enabled by using the block_coverage_mode option.
For each module, the last relevant covers.set_cover_block() method call defines its block coverage
collection behavior.
Tip

Using set_cover_block() to disable block coverage data collection for a given module does not
reduce the performance overhead of block coverage data collection for this module. To reduce the
performance overhead, do not enable the module for block coverage at load time by using the
block_coverage_mode option.

23.5.6

covers.set_cover_check()

Purpose
Turns coverage data collection and display on or off for specified check or expect items

Category
Predefined method of the predefined struct global.covers

Syntax
covers.set_cover_check(check-name: string, enable: bool)

Parameters
check-name

A string of the form struct-name.check-expect-name[(instance-name)], where


instance-name is one of the following:

per_type for the per_type instance of the check


e_path==sys.unit-inst[....] for check instances enclosed by unit instances

Note
enable

Wildcards are allowed for all parts of the check-name.

Set to TRUE to turn on coverage for the specified check, or FALSE to turn coverage off
for this check.

Specman e Language Reference


1999-2015

1241
.

Product Version 15.1


All Rights Reserved.

Description
The collect_checks_expects option to the configure coverage command controls whether coverage
data is collected for check and expect items. If collect_checks_expects is set to TRUE, you can use the
set_cover_check() method to turn coverage data collection on or off for specified checks or expects.
Note If collect_checks_expects is set to FALSE, which is the default, no coverage is collected for
check and expect items, and the set_cover_check() method is ignored.
When the check-expect-name part of the check-name is a pure wildcard (*), this command affects both
checks/expects with explicit names, and checks/expects with implicit namesassigned names of the
form type-name_[check|expect]_index, where index is the index number of the check within the unit,
starting at 0. When the check-expect-name part of the check-name is not a pure wildcard, only checks
and expects with explicit names are included in the data collection.
For each check and expect, the last relevant call to cover.set_cover_check() specifies whether its data
is collected or not. If there is no relevant call to cover.set_cover_check(), coverage data will be
collected for it.
In the following example:

The first call to set_cover_check() on line 12 disables coverage data collection for all checks defined
in my_unit.
The second call on line 13 enables coverage collection for check1. It does not enable the check on
line 5, even though its implicit name matches the wildcard.
The third call on line 14 disables coverage collection for the my_u1 instance of check1.
1
unit my_unit {
2
my_checks() is {
3
check check1 that 5 > 3;
4
check ch that 2*2 = 4;
5
check that 8 > 5; // Implicit name is my_unit_check_2
6
};
7
};
8
extend sys {
9
my_u1: my_unit is instance;
10
my_u2: my_unit is instance;
11 setup() is also {
12
covers.set_cover_check("my_unit.*", FALSE);
13
covers.set_cover_check("my_unit.*check*", TRUE);
14
covers.set_cover_check("my_unit.check1(e_path==sys.my_u1)", FALSE);
15
};
16 };

See Also

covers.set_cover() on page 1237

Specman e Language Reference


1999-2015

1242

Product Version 15.1


All Rights Reserved.

configure cover in the Specman Command Reference

About Test Coverage in Managing Coverage for e Testbenches

show cover in the Specman Command Reference

23.5.7

covers.set_per_inst_for_struct()

Purpose
Collect coverage data for structs in a unit

Category
Predefined method of the predefined struct global.covers

Syntax
covers.set_per_inst_for_struct(struct-type: string, unit-type: string)

Parameters
struct-type

Name of the struct type for which to set this per-instance behavior

unit-type

Defines the units for which to collect per-instance results of the struct coverage
entities:

Empty string ()Per get_unit()


unit-typeThe first enclosing unit of unit-type type1
sysDisable per-instance collection defined by the previous use of this method

1. The enclosing unit of a struct instance is, by default, the unit instance in which the struct is
instantiated. You can change the enclosing unit of a struct instance by using the
any_struct.set_unit(any-unit) method.

Description
By default, coverage entities in structs are collected only per type. You can change this default behavior
by using this method, as follows:

Provide a non-empty unit-type parameter

Specman e Language Reference


1999-2015

1243
.

Product Version 15.1


All Rights Reserved.

All coverage groups, check/expects, and blocks in the struct are added to the coverage model for
each instance of unit-type.
When a coverage group, check/expect, or block is sampled for an instance of this struct, this sample
is added to the coverage instance of the first enclosing unit from the unit-type type.
If unit-type=sys, only per-type coverage is collected for the structs coverage entities. You can use
this feature to override a previous use of this method for this struct.

Provide an empty unit-type parameter ()


If you do not provide a unit-type value, all coverage entities in the struct are added to the coverage
model of its enclosing unit instance the first time any of the coverage entities in the struct instance
is sampled.
When one of these coverage entities is sampled for a struct instance, the sample is added to the
coverage data for the first enclosing unit.

Tip

Providing the optional unit-type improves performance, because it adds all of the per-instance
information about coverage entities in the struct at the end of the generation phase, rather than
repeatedly updating the model during the simulation run.

Tip

Including the unit-type creates a full model that contains all coverage entities, whether covered or
not. Omitting this option might not produce a full model.

You can use this method multiple times for the same type. The last method call overrides all previous
declarations.
Notes about using the set_per_inst_for_struct method:

This method applies only to coverage data generated for use with Enterprise Manager.
The per-instance coverage results for the struct will be shown in the Enterprise Manager vplan window
under the enclosing-unit-e-path.struct-type-name instance.
This method affects the per-instance coverage collection for struct-type and all of its like and when
subtypes.
This method applies only to coverage groups for which there is no explicit per_unit_instance
declaration. Coverage data collection for any coverage group with an explicit per_unit_instance
setting is not affected.
This method is not supported for units. Using it in a unit results in an ERR_PER_INST_COV_UNIT
error.
An error is reported if you call this method after the setup phase.
You can disable the implicit per-instance coverage for unit instances by using the per_inst_cover
unit attribute. Doing so also disables implicit per-instance coverage data collection for struct coverage
entities that are collected for this unit instance.

Specman e Language Reference


1999-2015

1244

Product Version 15.1


All Rights Reserved.

23.5.8

covers.get_contributing_runs()

Purpose
Return a list of the test runs that contributed samples to a bucket

Category
Predefined method of the predefined struct global.covers

Syntax
covers.get_contributing_runs(item-name: string, bucket-name: string): list of string
Syntax Example
print covers.get_contributing_runs("inst.done.opcode", "JMP");

Parameters
item-name

A string, enclosed in double quotes, specifying the coverage item that contains
bucket-name. The string has the form struct-name.group-name.item-name, where
group-name is:
event-name[(instance-name)]
and where instance-name is one of the following:
per_type
item-name == bucket-name (for item instance sub-groups)
e-path-exp (for cover group instances)
and where e-path-exp has the following form:

e_path==sys.unit-inst[....]
bucket-name

A string, enclosed in double quotes, specifying the bucket for which contributing test
run names are to be listed.
The bucket name must be written in its canonical form (as displayed by show cover).
See Canonical Naming Conventions in the Specman Integrators Guide for more
information.

Specman e Language Reference


1999-2015

1245
.

Product Version 15.1


All Rights Reserved.

Description
This method returns a list of strings that are the full run names of the test runs that placed samples in a
specified bucket.

Example
The following e code defines a cover group done that includes four items: an operation, two opcodes,
and a cross between the operation and the register opcode.
type cpu_opcode: [ADD, SUB, OR, AND, JMP, LABEL];
type cpu_reg: [reg0, reg1, reg2, reg3];
struct inst {
opcode: cpu_opcode;
op1: cpu_reg;
op2: byte;
event done;
cover done is {
item opcode;
item op1;
item op2;
cross opcode, op1 using name = opcode_op1;
};
};

The following Specman commands (which might appear in an ecom file) first read in the coverage
database for multiple tests, and then list the full names of the test runs that placed samples in the ADD
bucket for inst.done.opcode and the ADD/reg2 bucket for inst.done.opcode_op1:
Read cover cov_work/scope/*test*/sn*.ucd; // read multiple tests
print covers.get_contributing_runs("inst.done.opcode", "ADD");
print covers.get_contributing_runs("inst.done.opcode_op1", "ADD/reg2");

See Also

About Predefined Coverage Groups in Managing Coverage for e Testbenches

Specifying Buckets in Managing Coverage for e Testbenches

Making Ungradable Items Gradable in Managing Coverage for e Testbenches

23.5.9

covers.get_unique_buckets()

Purpose
Return a list of the names of unique buckets from specific tests.
Specman e Language Reference
1999-2015

1246

Product Version 15.1


All Rights Reserved.

Category
Predefined method of the predefined struct global.covers

Syntax
covers.get_unique_buckets(file-name: string): list of string
Syntax Example
print covers.get_unique_buckets("test_rx")

Parameters
file-name

A string, enclosed in double quotes, specifying the coverage database files for
which you want to see unique buckets. You cannot use wild cards in the file name.

Description
A unique bucket is a bucket that is covered by only one test. This command reports, for each specified
test, the full names of its unique buckets, if there are any.

Note
You must rank the tests with the rank cover command before calling covers.get_unique_buckets().

Example
The following example shows how to display a list of unique buckets that are covered by a test. The
results of the test ranking show that the test CPU_tst2_1 has three unique buckets. Passing this test
name to covers.get_unique_buckets() retrieves the names of the buckets.
cmd-prompt> restore top
// Restore the cover definitions
Specman CPU_top> read cover */*/*/sn*.ucd // Read in test data
Reading cov_work/scope/CPU_tst1_sn1/sn.ucd ...
Reading cov_work/scope/CPU_tst2_sn1/sn.ucd ...
Reading cov_work/scope/CPU_tst3_sn7/sn.ucd ...
Reading cov_work/scope/CPU_tst4_sn7/sn.ucd ...
Reading cov_work/scope/CPU_tst8_sn7/sn.ucd ...
5 coverage files read in.
Specman CPU_top> rank cover -sort_only

// Rank the tests

Coverage Ranking Report


========================
Specman e Language Reference
1999-2015

1247
.

Product Version 15.1


All Rights Reserved.

Specman Coverage Test-Ranking report


====================================
Command:
rank cover -sort_only *.*.*
Grading_formula:
linear
Ranking Cost:
cpu_time
At least multiplier: 1
Number of tests:
5
Maximal Grade:
0.87
Note:
All test grades are given as precentage from Maximal
Grade
The Sorted Test List:
----------------------Cum.
Rel.
Cum.
Abs.
EfficNum Test name
Grade Grade Cost
Cost
Grade iency UB
--- ------------------------- ------ ------ ----- ----- ---- ------ ---1
CPU_tst3_7
N/A
N/A
N/A
7
0.86
0.74 0
2
CPU_tst4_7
N/A
N/A
N/A
7
0.86
0.74 0
3
CPU_tst8_7
N/A
N/A
N/A
7
0.86
0.74 0
4
CPU_tst2_1
N/A
N/A
N/A
7
0.85
0.72 3
5
CPU_tst1_1
N/A
N/A
N/A
6
0.66
0.66 0
--- --------------------------- ------ ------ ------ ------ -----Specman CPU_top> print covers.get_unique_buckets("CPU_tst2_1")
covers.get_unique_buckets("CPU_tst2_1") =
0.
"instr.start_drv_DUT.cross__opcode__carry:
ANDI/1"
1.
"instr.start_drv_DUT.cross__opcode__carry:
XORI/1"
2.
"instr.start_drv_DUT.cross__opcode__carry:
NOP/1"
Specman CPU_top>

See Also

About Predefined Coverage Groups in Managing Coverage for e Testbenches

Specifying Buckets in Managing Coverage for e Testbenches

Making Ungradable Items Gradable in Managing Coverage for e Testbenches

23.5.10 covers.write_cover_file()
Purpose
Write the coverage results during a test

Specman e Language Reference


1999-2015

1248

Product Version 15.1


All Rights Reserved.

Category
Predefined method of the predefined struct global.covers

Syntax
write_cover_file();
Syntax Example
write_cover_file();

Description
This method writes the coverage results .ucd file during a test run. It can only be invoked during a test,
not before the run starts nor after it ends.
The coverage file written by this method does not contain the session.end_of_test or session.events
coverage groups.

Example
This example writes the current coverage results to the .ucd file whenever the event named sys.cntr is
emitted.
<'
struct top {
event wr_cov is @sys.cntr;
on wr_cov {
write_cover_file();
};
};
'>

See Also

configure cover in the Specman Command Reference

23.5.11 covers.compute_overall_grade()
Purpose
Return the normalized overall coverage grade for the current set of tests

Specman e Language Reference


1999-2015

1249
.

Product Version 15.1


All Rights Reserved.

Category
Predefined method of the predefined struct global.covers

Syntax
covers.compute_overall_grade(): int;
Syntax Example
grade = covers.compute_overall_grade();

Description
This method returns an integer that represents the overall coverage grade for the current set of tests.
The value is a normalized value between 1 and 100M. To obtain a value equivalent to the overall grade,
divide the returned value by 100M.

Example
<'
struct top{
event e;
a: uint(bits: 4);
b: uint(bits: 4);
cover e is {
item a;
item b;
};
run() is also {emit e;};
};
extend sys {
toplist[10]: list of top;
finalize() is also {
var grade: int;
grade = covers.compute_overall_grade();
print grade;
};
};
'>

See Also

covers.get_overall_grade() on page 1251

Specman e Language Reference


1999-2015

1250

Product Version 15.1


All Rights Reserved.

Grading Coverage in Managing Coverage for e Testbenches

covers.get_ucd_path() on page 1252

covers.get_test_name() on page 1253

covers.get_seed() on page 1255

23.5.12 covers.get_overall_grade()
Purpose
Return the normalized overall coverage grade for the most recently analyzed group or item

Category
Predefined method of the predefined struct global.covers

Syntax
covers.get_overall_grade(): int;
Syntax Example
grade = covers.get_overall_grade();

Description
This method returns an integer that represents the overall coverage grade for the most recently analyzed
coverage group or item. For example, if you specify a particular item or group with show cover, a
subsequent print covers.get_overall_grade() displays the grade for that item or group.
Since Specman does not handle floating point types, the value is a normalized value between 1 and
100M. To obtain a value equivalent to the overall grade, divide the returned value by 100M.

Example
cmd-prompt> show cover inst.done.opcode
cmd-prompt> print covers.get_overall_grade();

See Also

covers.compute_overall_grade() on page 1249

Grading Coverage in Managing Coverage for e Testbenches

Specman e Language Reference


1999-2015

1251
.

Product Version 15.1


All Rights Reserved.

covers.get_ucd_path() on page 1252

covers.get_test_name() on page 1253

covers.get_seed() on page 1255

23.5.13 covers.get_ucd_path()
Purpose
Return the path for the .ucd file

Category
Predefined method of the predefined struct global.covers

Syntax
covers.get_ucd_path(): string;
Syntax Example
ucd_path = covers.get_ucd_path();

Description
This method returns the path for the .ucd file in which the current coverage results will be stored.
The actual name of the .ucd file that is stored in the path is:

sn_fuctional-coverage-checksum_block-coverage-checksum.ucd when the model checksum values


are computed during the model file (.ucm) dump before the .ucd file is dumped.
sn.ucd when the model file (.ucm) is not dumped for the the .ucd file is dumped.

Example
<'
struct top{
event e;
a: uint(bits: 4);
b: uint(bits: 4);
cover e is {
item a;
item b;
};
Specman e Language Reference
1999-2015

1252

Product Version 15.1


All Rights Reserved.

run() is also {emit e;};


};
extend sys {
toplist[10]: list of top;
finalize() is also {
var ucd_path: string;
ucd_path = covers.get_ucd_path();
print ucd_path;
};
};
'>

See Also

configure cover in the Specman Command Reference

covers.get_overall_grade() on page 1251

covers.get_test_name() on page 1253

covers.get_seed() on page 1255

23.5.14 covers.get_test_name()
Purpose
Return the name of the most recently loaded e file (the file containing the top module for the current test)

Category
Predefined method of the predefined struct global.covers

Syntax
covers.get_test_name(): string;
Syntax Example
test_file = covers.get_test_name();

Description
This method returns the name of the most recently loaded e file, minus the .e extension.

Specman e Language Reference


1999-2015

1253
.

Product Version 15.1


All Rights Reserved.

When you execute this method in code, the most recently loaded e file is the file that contains the top
module for the current test. The name of this file is generally referred to as the test name. Thus, you can
think of this method as a way to return the current test name.

Example
<'
struct top{
event e;
a: uint(bits: 4);
b: uint(bits: 4);
cover e is {
item a;
item b;
};
run() is also {emit e;};
};
extend sys {
toplist[10]: list of top;
finalize() is also {
var test_id: string;
test_id = covers.get_test_name();
print test_id;
};
};
'>

Result
...
test_id = "cpu_test1"
...

This result tells you that the file cpu_test1.e contains the top module for the current test.

See Also

configure cover in the Specman Command Reference

covers.get_overall_grade() on page 1251

covers.get_ucd_path() on page 1252

covers.get_seed() on page 1255

Specman e Language Reference


1999-2015

1254

Product Version 15.1


All Rights Reserved.

23.5.15 covers.get_seed()
Purpose
Return the value of the seed for the current test

Category
Predefined method of the predefined struct global.covers

Syntax
covers.get_seed(): int
Syntax Example
seed_val= covers.get_seed();

Description
This method returns the current test seed.

Example
<'
struct top{
event e;
a: uint(bits: 4);
b: uint(bits: 4);
cover e is {
item a;
item b;
};
run() is also {emit e;};
};
extend sys {
toplist[10]: list of top;
finalize() is also {
var test_seed: int;
test_seed = covers.get_seed();
print test_seed;
};
};
'>
Specman e Language Reference
1999-2015

1255
.

Product Version 15.1


All Rights Reserved.

Result
...
test_seed = 1
...

See Also

configure cover in the Specman Command Reference

covers.get_overall_grade() on page 1251

covers.get_ucd_path() on page 1252

covers.get_test_name() on page 1253

23.5.16 covers.set_unicov_hier()
Purpose
Change the instance path of all coverage instances of a unit instance

Category
Predefined method of the predefined struct global.covers

Syntax
covers.set_unicov_hier(inst: any_unit, path: string)
Syntax Example
covers.set_unicov_hier(me, full_external_uvm_path());

Parameters
inst

A pointer to the unit instance for which to modify the instance path

path

The configured instance path to use for the inst unit instance instead of the e path

Specman e Language Reference


1999-2015

1256

Product Version 15.1


All Rights Reserved.

Description
Changes the instance path of all covergroups, checks/expects, and block coverage instances of a
specified unit instance. For example, if you have a SystemVerilog interface for an e UVC unit, you can
use the set_unicov_hier() method to print or display the per-instance coverage results for this unit using
the SystemVerilog path, rather than the e path.
In the output, Specman creates an instance for each hierarchical element of the specified instance path.

Notes

The default instance path for unit instances is the e path, unless this method is used to change the path.
Covergroup instances that have instance names set using the instance_name option are not affected
by this method.
If this method is called more than once on the same unit instance, the last call overrides any previous
call.

If the path parameter is an empty string, the e path is used for this unit instance.

The following run-time error is reported if this method is called after the generation phase:
ERR_DEF_UNICOV_HIER_AFTER_GEN

This method affects only the specified inst instance. Descendents of this unit in the unit tree are not
affected.
This method affects coverage elements in structs that are mapped to inst by using the
covers.set_per_inst_for_struct() method.

Example
<'
unit u {
b: bit;
event ev;
cover ev is {
item b;
};
run() is also {
emit ev;
};
post_generate() is also {
// If external_uvm_path() is set for this instance, use it
// instead of the e path.
covers.set_unicov_hier(me, full_external_uvm_path());
};
Specman e Language Reference
1999-2015

1257
.

Product Version 15.1


All Rights Reserved.

};
extend sys {
u1: u is instance;
u2: u is instance;
keep u2.external_uvm_path() == "uvm_top.my_inst2";
};
'>

23.5.17 covers.set_cross_instance_collection()
Purpose
Enable/disable coverage data collection for each relevant unit instance of a coverage group with a
per_instance item

Category
Predefined method of the predefined struct global.covers

Syntax
covers.set_cross_instance_collection(inst_wc: any_unit, path_wc: string, enable: bool)
Syntax Example
covers.set_cross_instance_collection("u.ev(ab==A)", "*.au*", TRUE);

Parameters
inst_wc

All per_instance coverage items that match this wildcard


The name of the per-item covergroup instance is
struct-name.group-name(instance-name)
where instance-name is one of the following:

path_wc

per_type

item-name == bucket-name

All relevant unit instances that match this wildcard

Specman e Language Reference


1999-2015

1258

Product Version 15.1


All Rights Reserved.

enable

If TRUE, enables collection of each per-item covergroup instance that matches the inst_wc
wildcard, for each relevant unit instance whose name matches the path_wc wildcard.

Description
You can use this method to collect per-unit-instance coverage data for covergroups that have
per_instance items as well.
This method lets you enable or disable coverage data collection for each relevant unit instance of a
coverage group with a per_instance item.
A unit instance, inst, of type unit-type is relevant for per-unit-instance data collection for a covergroup if
the covergroup is defined:

In unit-type or
In a struct whose coverage information was mapped to unit-type by using the
covers.set_per_inst_for_struct() method or
In a struct whose coverage information was set to be collected for its enclosing unit by using
covers.set_per_inst_for_struct() with an empty unit-type parameter, and inst is an enclosing unit
of an instance of that struct

Notes

Coverage data will not be collected for unit instances whose data collection was disabled by the
per_inst_cover unit attribute.

The coverage results created by this method can only be viewed in Enterprise Manager.

Calling this method after the setup phase results in the following run-time error:
ERR_SET_CROSS_INST_COVER_AFTER_SETUP

23.5.18 covers.get_top_size_items()
Purpose
Prints which item definitions contributed the largest number of buckets when dumping the latest ucm
file.

Category
Predefined method of the predefined struct global.covers

Specman e Language Reference


1999-2015

1259
.

Product Version 15.1


All Rights Reserved.

Syntax
get_top_size_items(num_of_items_to_display: int);
Syntax Example
get_top_size_items(10);Description

The get_top_size_items() method creates a report of the item definitions that contributed the largest
number of buckets when dumping the latest ucm file.
The number of contributed buckets of an item definition is determined by the <number of buckets per
item's instance> * <number of item's instances>.
Note

This method can only be called after a ucm file was created; otherwise an error will be issued.

Example
To show the top 10 items which contributed the largest number of buckets issue, covers.
get_top_size_items(10) the following command from command line after the ucm file was created:
get_top_size_items(10)

23.6 Scheduler Methods


The scheduler is a predefined struct containing methods that let you access active TCMs and terminate
them.
A TCM that is invoked with a start action is a thread. If a started TCM calls other TCMs, those TCMs
are considered subthreads of the started TCM thread. If a struct has more than one started TCM, each
TCM runs on a separate, parallel thread. Each thread shares a unique identifier, or thread handle, with its
subthreads. The thread handle is automatically assigned by the scheduler.
The following sections describe how to retrieve the handle for active threads:

scheduler.get_current_handle() on page 1261

scheduler.get_handles_by_name() on page 1263

scheduler.get_handles_by_type() on page 1265

The following sections describe how to terminate active threads:

scheduler.kill() on page 1267

scheduler.terminate_branch() on page 1269

scheduler.terminate_thread() on page 1271

Specman e Language Reference


1999-2015

1260

Product Version 15.1


All Rights Reserved.

23.6.1

scheduler.get_current_handle()

Purpose
Obtain the handle of the current TCM

Category
Predefined method of the predefined struct global.scheduler

Syntax
scheduler.get_current_handle(): thread_handle
Syntax Example
out ("(started) I = ",i," in Thread " ,
scheduler.get_current_handle(),".");

Description
Returns the handle of the currently running TCM. The handle is of the predefined type named
thread_handle.
This method must ultimately be invoked from a TCM. You can call it from a non-TCM method, but that
method must, at some point, be called from a TCM. That is, you can call get_current_handle() from a
non-TCM, which, in turn, is called from another non-TCM, and so on, but at the top of the chain of
method calls must be a TCM.

Note
A runtime error is produced if get_current_handle() is called from within a regular (not
time-consuming) method, if that method is not ultimately called from a TCM.

Example
<'
struct sch {
run() is also {
start started_tcm(13);
start started_tcm(29);
};
started_tcm(i:int) @sys.any is {
Specman e Language Reference
1999-2015

1261
.

Product Version 15.1


All Rights Reserved.

out ("(started) I = ",i," in Thread " ,


scheduler.get_current_handle(),".");
called_tcm(i);
wait [1];
out ("(cont ..) I = ",i," in Thread " ,
scheduler.get_current_handle(),". (same thread handle)");
};
called_tcm(i:int) @sys.any is {
out ("(called ) I = ",i," in Thread " ,
scheduler.get_current_handle(),". (same thread handle)");
};
};
extend sys {
pmi: sch;
};
'>

Result
cmd-prompt> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
(started) I = 13 in Thread 1.
(called ) I = 13 in Thread 1. (same thread
(started) I = 29 in Thread 2.
(called ) I = 29 in Thread 2. (same thread
(cont ..) I = 13 in Thread 1. (same thread
(cont ..) I = 29 in Thread 2. (same thread
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT

handle)
handle)
handle)
handle)
warnings.

See Also

scheduler.get_handles_by_name() on page 1263

scheduler.get_handles_by_type() on page 1265

Specman e Language Reference


1999-2015

1262

Product Version 15.1


All Rights Reserved.

23.6.2

scheduler.get_handles_by_name()

Purpose
Get list of thread handles on a struct instance basis

Category
Predefined method of the predefined struct global.scheduler

Syntax
scheduler.get_handles_by_name(struct-inst: exp, method-name: string): list of thread_handle
Syntax Example
hs = scheduler.get_handles_by_name(a1,"yy");

Parameters
struct-exp

NULL, or an expression of type struct that specifies the owning struct instance for
the started TCMs with the specified name.

method-name

NULL, or the name of a method in the specified struct, enclosed in double quotes.

Description
Returns a list of handles of all started TCMs of the specified name associated with the specified struct
instance.
When the struct expression is NULL the resulting list contains handles for all the started TCMs of the
given name. When the method name is NULL, the returned list contains thread handles for all the
currently running threads for the specified struct. In the case when both parameters are NULL, the list of
handles for all currently running threads is returned.
A thread is any started TCM. If a started TCM calls other TCMs, those TCMs are considered subthreads
of the started TCM thread. If a struct has more than one started TCM, each TCM runs on a separate,
parallel thread. Each thread shares a unique identifier, or thread handle, with its subthreads. The thread
handle is automatically assigned by the scheduler.

Example
<'
Specman e Language Reference
1999-2015

1263
.

Product Version 15.1


All Rights Reserved.

struct a {
xx() @sys.any is {
wait [1]*cycle;
};
yy() @sys.any is {
wait [1]*cycle;
};
};
extend sys {
a1:a;
a2:a;
run() is also {
var hs:list of thread_handle;
start a1.xx();
start a1.yy();
start a2.yy();
hs = scheduler.get_handles_by_name(a1,"yy");
print hs;
print scheduler.get_handles_by_name(NULL,NULL);
};
};
'>

Result
cmd-prompt> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
hs =
0.
2
scheduler.get_handles_by_name(NULL,NULL) =
0.
1
1.
2
2.
3
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

scheduler.get_current_handle() on page 1261

scheduler.get_handles_by_type() on page 1265

Specman e Language Reference


1999-2015

1264

Product Version 15.1


All Rights Reserved.

23.6.3

scheduler.get_handles_by_type()

Purpose
Get list of thread handles on a struct type basis

Category
Predefined method of the predefined struct global.scheduler

Syntax
scheduler.get_handles_by_type(struct-inst: exp, method-name: string): list of thread_handle
Syntax Example
hs = scheduler.get_handles_by_type("a","yy");

Parameters
struct-exp

NULL, or an expression of type struct that specifies the owning struct type for the
top-level TCMs of the specified method.

method-name

NULL, or the name of a method in the specified struct, enclosed in double quotes

Description
Returns handles to all TCMs associated with the specified struct type.
When the struct expression is NULL the resulting list contains handles for all the started TCMs of the
given name. When the method name is NULL, the returned list contains thread handles for all the
currently running threads for the specified struct. If both struct expression and method name are NULL,
then all handles of all currently running threads are returned.
A thread is any started TCM. If a started TCM calls other TCMs, those TCMs are considered subthreads
of the started TCM thread. If a struct has more than one started TCM, each TCM runs on a separate,
parallel thread. Each thread shares a unique identifier, or thread handle, with its subthreads. The thread
handle is automatically assigned by the scheduler.

Example
<'
struct a {
Specman e Language Reference
1999-2015

1265
.

Product Version 15.1


All Rights Reserved.

xx() @sys.any is {
wait [1]*cycle;
};
yy() @sys.any is {
wait [1]*cycle;
};
};
extend sys {
a1:a;
a2:a;
run() is also {
var hs:list of thread_handle;
start a1.xx();
start a2.yy();
start a2.yy();
hs = scheduler.get_handles_by_type("a","yy");
print hs;
print scheduler.get_handles_by_type("a",NULL);
};
};
'>

Result
cmd-prompt> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
hs =
0.
2
1.
3
scheduler.get_handles_by_type("a",NULL) =
0.
1
1.
2
2.
3
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

scheduler.get_current_handle() on page 1261

scheduler.get_handles_by_name() on page 1263

Specman e Language Reference


1999-2015

1266

Product Version 15.1


All Rights Reserved.

23.6.4

scheduler.kill()

Purpose
Kill a specified thread

Category
Predefined method of the predefined struct global.scheduler

Syntax
scheduler.kill(handle: thread_handle)
Syntax Example
for each (h) in hs {
{scheduler.kill(h)};
};

Parameters
handle

The handle for the thread, as returned by scheduler.get_current_handle(),


scheduler.get_handles_by_name(), or scheduler.get_handles_by_type().

Description
Kills a started TCM (a thread) and any TCMs that it has called (its subthreads). A killed method cannot
be revived.

Notes

Killing a method before it frees an active lock can result in a dead lock.

A thread cannot kill itself. Use scheduler.terminate_thread() on page 1271 instead.

Example
<'
struct p_agent {
killer_tcm() @sys.any is {
wait [1]*cycle;
var hs :=
Specman e Language Reference
1999-2015

1267
.

Product Version 15.1


All Rights Reserved.

scheduler.get_handles_by_type("p_agent","send");
for each (h) in hs {
out("Killing thread ",h);
{scheduler.kill(h)};
};
};
send() @sys.any is {
wait [5]*cycle;
out ("this line is never executed. ");
};
};
extend sys {
x:p_agent;
run() is also {
start x.killer_tcm();
start x.send();
start x.send();
start x.send();
};
};
'>

Result
cmd-prompt> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
Killing thread 2
Killing thread 3
Killing thread 4
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

scheduler.terminate_branch() on page 1269

scheduler.terminate_thread() on page 1271

Specman e Language Reference


1999-2015

1268

Product Version 15.1


All Rights Reserved.

23.6.5

scheduler.terminate_branch()

Purpose
Terminate a specific branch in a first of action

Category
Predefined method of the predefined struct global.scheduler

Syntax
scheduler.terminate_branch()
Syntax Example
scheduler.terminate_branch();

Description
This method can be used only within a first of action to terminate the branch. When a branch is
terminated using this method, the rest of the branches within the first of action remain active.

Example
The TCM monitor() in the example below begins several threads. Each waits for a sequence of events.
Under some conditions, some of the sequences should be halted.
<'
extend sys {
monitor() @sys.any is {
wait until rise('top.started');
first of {
{
wait [4] * cycle;
if 'top.out_of_sync' == 1 then {
out("### Went out of sync");
scheduler.terminate_branch();
};
wait until rise('top.ended');
out("Normal end");
};
{
wait until rise('top.aborted');

Specman e Language Reference


1999-2015

1269
.

Product Version 15.1


All Rights Reserved.

out("Aborted");
};
};
// continue monitoring...
stop_run();
};
run() is also {
start monitor();
};
};
extend sys {
drive() @sys.any is {
wait [2] * cycle;
'top.started' = 1;
wait [5] * cycle;
'top.out_of_sync' = 1;
};
run() is also {
start drive();
};
};
'>

Result
cmd-prompt> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
### Went out of sync
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

scheduler.kill() on page 1267

scheduler.terminate_thread() on page 1271

Specman e Language Reference


1999-2015

1270

Product Version 15.1


All Rights Reserved.

23.6.6

scheduler.terminate_thread()

Purpose
Terminate the current thread

Category
Predefined method of the predefined struct global.scheduler

Syntax
scheduler.terminate_thread()
Syntax Example
scheduler.terminate_thread();

Description
Terminates the current thread immediately, not at the end of the current tick. To terminate the current
thread at the end of the current tick, use quit().
A thread is any started TCM. If a started TCM calls other TCMs, those TCMs are considered subthreads
of the started TCM thread. If a struct has more than one started TCM, each TCM runs on a separate,
parallel thread. Each thread shares a unique identifier, or thread handle, with its subthreads. The thread
handle is automatically assigned by the scheduler.

Example
The TCM inject() in the example below assigns the DUT signals. There are some conditions during the
run that indicate that the injection should stop.
<'
extend sys {
inject() @sys.any is {
'top.data' = 1;
wait [10] * cycle;
// continue reading/writing...
if ('top.status' == 0) then {
out("'top.status' == 0, Stop injection");
scheduler.terminate_thread();
};
// continue reading/writing...
Specman e Language Reference
1999-2015

1271
.

Product Version 15.1


All Rights Reserved.

};
run() is also {
start inject();
};
};
'>

Result
cmd-prompt> test
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
'top.status' == 0, Stop injection
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

The quit() Method of any_struct or any_unit on page 1189

scheduler.kill() on page 1267

scheduler.terminate_branch() on page 1269

23.7 Simulation-Related Methods

simulator.get_define() on page 1272

is_stub_required() / get_stub_reason() on page 1274

See Also

The remap_tick_access() Method of sys on page 1173

Chapter 17 Simulation-Related Constructs

23.7.1

simulator.get_define()

Purpose
Get the value of a Verilog define

Specman e Language Reference


1999-2015

1272

Product Version 15.1


All Rights Reserved.

Category
Predefined method of the predefined struct global.simulator

Syntax
simulator.get_define(macro: string): string
Syntax Example
s = simulator.get_define("WORD_WIDTH");

Parameters
macro

A currently defined Verilog macro, with the leading ` character, enclosed in double quotes.

Description
Returns the value of the Verilog macro as a string. If no such define exists, an error occurs. A typical
reason to use this method, rather than the more concise `macro notation, is when you need to compute
the define string during run time.
This method works for both normal and deferred defines.

Example
macros.v
define BASIC_DELAY
2
ifdef OLD_TECH
define TRANS_DELAY
else
define TRANS_DELAY
endif
define TOP
tb
define READY TOP.ready
define WORD_WIDTH 8
define HIGH_BIT
7

BASIC_DELAY+3
BASIC_DELAY

defs.e
<'
verilog import macros.v;
struct defs {
Specman e Language Reference
1999-2015

1273
.

Product Version 15.1


All Rights Reserved.

m() is {
var s : string;
s = simulator.get_define("WORD_WIDTH");
print s;
};
};
extend sys {
pmi: defs;
};
'>

Result
cmd-prompt> sys.pmi.m()
s = "8"

See Also

verilog import on page 840

specman deferred on page 899

show defines of the Specman Command Reference

23.7.2

is_stub_required() / get_stub_reason()

Purpose
is_stub_required(): Identify whether a stubs file is required for the current port.
get_stub_reason(): Print the reason why a stubs file is required for the current port.

Category
Predefined Method

Syntax
is_stub_required(): bool
get_stub_reason(): string

Specman e Language Reference


1999-2015

1274

Product Version 15.1


All Rights Reserved.

Description
Specman uses a stubs file as a primary interface for communication with the simulator. The stubs file
contains Specman modules or entities (written in the language used by the DUT) that enable integration
with the simulator or waveform viewer.
There are, however, several scenariosfor example, accessing a Verilog part selectin which a stubs
file is not required. In such scenarios, you can set the pli_access() port attribute to TRUE. For scenarios
where a stubs file is required, it can be useful to know why it is required to ensure that the stubs file is
regenerated appropriately. In general, the stubs file must be regenerated each time you change the
parameters for an e external port, such as one of the port attributes.
The following predefined methods provide helpful information regarding the stubs file:

is_stub_required() returns TRUE if a stubs file is required for the current port and FALSE if a stubs
file is not required for the current port.
For ports that require a stubs file, get_stub_reason() provides the reason why the stubs file must be
regenerated if the port changes.

Important

These methods are available only after the stubs file is created or during simulation time.

These methods work only with Verilog or SystemVerilog.

Example
The following e code defines the unit u_ports_need_stub to include a simple indexed external port and
a simple external port that includes the verilog_wire() attribute:
unit U {
method_type mt(i: int);
};
unit u_ports_needed_stub {
index_port: inout simple_port(mt) of int is instance;
keep index_port.hdl_path() == "ip";
keep index_port.hdl_expression() == "<p>[<i>]";
verilog_wire_p: out simple_port of bit is instance;
keep verilog_wire_p.hdl_path() == "w";
keep verilog_wire_p.verilog_wire() == TRUE;
};

The following e code extends global to include the get_stub_report() method, which uses the two
methods is_stub_required() and get_stub_reason():
extend global {
Specman e Language Reference
1999-2015

1275
.

Product Version 15.1


All Rights Reserved.

get_stub_report() is {
for each (p) in sys.get_ports_recursively() {
out("");
if (p.is_stub_required()) {
out("HDL path: ", str_join(p.get_hdl_path_list(), "."));
out("e path: ", p.e_path());
out("Stub reason: ", p.get_stub_reason());
out("");
};
};
};
};

Result
If you run the get_stub_report() method after the stubs file is created, you get the following result. This
result tells you that a stubs file is required for the following ports:

index_port because it is a simple indexed port.

verilog_wire_p because it is a simple port with verilog_wire() defined.


HDL path: ip
e path: sys.u_stub.index_port
Stub reason: simple indexed port
HDL path: w
e path: sys.u_stub.verilog_wire_p
Stub reason: simple port with : verilog_wire

See Also

write stubs in the Specman Command Reference

pli_access() Port Attribute rin the Specman Integrators Guide

23.8 Semaphore and Locker Methods


The e language provides three predefined structs that are useful in controlling resource sharing among
TCMs:

semaphore
This is the typical semaphore. The maximum value ranges between 1 and MAX_INT. By default, it
is MAX_INT, and the initial value (number of available resources) is 0. (See Example 1 on page
1280.)

rdv_semaphore

Specman e Language Reference


1999-2015

1276

Product Version 15.1


All Rights Reserved.

A rendezvous semaphore is a semaphore with no resources. It requires the meeting of a producer


and a consumer for either to proceed. When they finally proceed, the down() thread always runs
first, followed immediately by the up(). (See Example 2 on page 1282.)
Note Table 23-1 gives a brief description of the predefined methods of the semaphore and
rdv_semaphore structs.

locker
The methods of this struct provide a fair, FIFO-ordered sharing of a resource between multiple
competing methods. The lock() and free() methods (Table 23-2 on page 1277) must be issued by the
same entity. Only the thread that locked the locker can release it.

For usage details, see Using Semaphores and Lockers on page 1278.
Table 23-1

Semaphore Methods

Method

Description

up()

Increments the semaphore's value. Blocks if the value is already the


maximum possible.

down()

Decrements the semaphore's value. Blocks if the value is already 0.

try_up()

Increments the semaphore's value. If the value is already the maximum


possible, returns without blocking.

try_down()

Decrements the semaphore's value. If the value is already 0, returns without


blocking.

set_value()

Sets the initial value of the semaphore.

get_value()

Returns the current value of the semaphore.

set_max_value()

Sets an upper limit to the possible value of the semaphore.

get_max_value()

Returns the maximum possible value.

Table 23-2

Locker Methods

Method

Description

lock()

The first TCM to call the lock() method of a field of type locker gets the
lock and can continue execution. The execution of the other TCMs is
blocked.

Specman e Language Reference


1999-2015

1277
.

Product Version 15.1


All Rights Reserved.

Table 23-2

Locker Methods

Method

Description

free()

When a TCM that has the lock calls free(), control goes to the next TCM
serviced by the scheduler that is waiting on the locker. The order in which
the lock is granted is by a FIFO (First In First Out) order of client lock()
requests.

See Also

Using Semaphores and Lockers on page 1278

How to Use the Semaphore Struct on page 1279

up() and down() on page 1279

try_up() and try_down() on page 1283

set_value() and get_value() on page 1285

set_max_value() and get_max_value() on page 1286

lock() and free() on page 1288

23.8.1

Using Semaphores and Lockers

You can use a semaphore when you need to implement a producer/consumer processthat is, one entity
locks the resource and the other one frees it.
You can also use a semaphore if you have more than one shared resource available. First, initialize the
number of resources available with set_value(). Then, when an entity uses one of the resources, it
decrements the semaphore number, indicating that one less resource is available. When it releases the
resource, it increments the semaphore number.
A locker is useful when a shared resource can be used by only one entity at a time.
Tip

When the rerun() predefined method is called, any existing lock requests remain in the locker
structure; they are not released. You can work around this limitation by using a semaphore to
implement the locker functionality, as follows:
1.

Initialize the semaphore count to 1, to duplicate the locker behavior.

2.

Use semaphore.down() instead of locker.lock() to obtain the resource.

3.

Use semaphore.up() instead of locker.free() to release the resource.

4.

Add try_up() to the rerun() method by extending it, as follows:


struct S { sem : semaphore;
...

Specman e Language Reference


1999-2015

1278

Product Version 15.1


All Rights Reserved.

rerun() is also {
var was_released: bool = sem.try_up();
if was_released {
out("locker released by rerun");
};
};
};

When rerun() executes the try_up() method on the semaphore, the resource is released.

23.8.2

How to Use the Semaphore Struct

A field of type semaphore typically serves as a synchronization object between two types of TCMs:
producer and consumer.
A consumer TCM uses the predefined down() time-consuming method of the semaphore to gain control
of a new resource managed by the semaphore. If no resources are available at the time down() is called,
the consumer TCM is blocked until such a resource is available.
A producer TCM uses the predefined up() time-consuming method of the semaphore to increase the
amount of available resources of the semaphore. This resource is made available for consumer TCMs. If
the semaphore already contains the maximum number of resources at the time up() is called, the
producer TCM is blocked until a semaphore resource is consumed.
The amount of available resources is zero by default but can be set otherwise using the set_value()
method. The current amount of available resources can be obtained using the get_value() method.
There is a limit to the possible number of available resources. Typically, the maximum is MAX_INT, but
it can be set to other values between 0 and MAX_INT using the set_max_value() method. The current
limit for available resources can be obtained using the get_max_value() method.
Any producer TCM is blocked if the semaphore already holds the maximum number of available
resources.

23.8.3

up() and down()

Purpose
Synchronize producer and consumer TCMs

Category
Predefined TCM of semaphore struct

Specman e Language Reference


1999-2015

1279
.

Product Version 15.1


All Rights Reserved.

Syntax
semaphore.up()
semaphore.down()
Syntax Example
sem1.up();
sem1.down();

Parameters
semaphore

An expression of type semaphore or rdv_semaphore

Description
The up() time-consuming method increases the number of available resources of the semaphore by 1. If
the number of available resources is already the maximum, the TCM is blocked. Blocked calls to up()
are serviced according to their request order (on a First In First Out basis).
The down() time consuming method decreases the number of resources of the semaphore by 1. If no
resources are available, the TCM is blocked. Blocked calls to down() are serviced according to their
request order (on a First In First Out basis).
With an rdv_semaphore, up() and down() are blocked unless they coincide. The down() TCM always
breaks the block first.

Example 1
The following example shows how you can use a semaphore to handle concurrent requests for exclusive
access from multiple clients in an orderly manner. In this example there are two client structs and one
server struct. The server has a semaphore to ensure that all requests are granted and that there are no
simultaneous grants.
When both clients issue a request at the same time the semaphore keeps track of the order of the
requesting TCMs. The first client to issue a request is granted the single resource, making it unavailable
to the other client. When this client is done with the resource, it uses the up() method of the semaphore
to make the resource available to the other requesting client.
<'
struct server {
event clk;
sem: semaphore;
run() is also {
Specman e Language Reference
1999-2015

1280

Product Version 15.1


All Rights Reserved.

sem.set_value(1);
};
};
struct client {
id: string;
s: server;
handshake()@s.clk is { // A single-cycle delay handshake
out(id,": Starting handshake at time ",sys.time);
s.sem.down();
out(id,": Granted at time ",sys.time);
wait [1];
out(id,": Releasing at time ",sys.time);
s.sem.up();
};
run()is also {start handshake();};
};
extend sys {
s: server;
c1: client; keep {c1.s==s; c1.id=="client 1"};
c2: client; keep {c2.s==s; c2.id=="client 2"};
go()@any is {
for i from 0 to 40 do {
wait cycle;
emit s.clk;
};
stop_run();
};
run()is also {start go()};
};
'>

Result:
client
client
client
client
client
client

1:
1:
2:
1:
2:
2:

Starting handshake at time 1


Granted at time 1
Starting handshake at time 1
Releasing at time 2
Granted at time 2
Releasing at time 3

Specman e Language Reference


1999-2015

1281
.

Product Version 15.1


All Rights Reserved.

Example 2
The following example shows how to use an rdv_semaphore to synchronize several reading TCMs that
share a common input source.
In this example there is one writer and two readers. It takes the writer 3 cycles to write its data, and then
it calls the up() method. When a reader appears, it calls the down() method and waits for the data to be
ready. When both the writer and the reader are ready, at the two sides of the channel, the data exchange
takes place: the reader breaks the block first, which allows it to read the data before it is overwritten by
the writer. Then comes the writer and starts preparing for the next data exchange.
<'
extend sys {
rdv_semaphore;
reg :int;
writer(id : int) @any is {
var v : int = 0;
while TRUE {
out(time, " -> writer ", dec(id), ": start preparing data.");
wait [3];
v += 1;
reg = v;
out(time, " -> writer ", dec(id),
": done writing to register [ v = ",hex(v),"].");
rdv_semaphore.up();
};
};
reader(id : int) @any is {
while TRUE {
out(time, " -> reader ", dec(id),
": ready to read from register.");
rdv_semaphore.down();
out(time, " -> reader ", dec(id),
": reading from register [ reg = ",hex(reg),"].");
wait [id];
};
};
run() is
start
start
start
};

also {
writer(1);
reader(2);
reader(3);

event terminate is [10] exec {stop_run();};

Specman e Language Reference


1999-2015

1282

Product Version 15.1


All Rights Reserved.

};
'>

Result:
0
0
0
3
3
3
5
6
6
6
9
9
9
9

->
->
->
->
->
->
->
->
->
->
->
->
->
->

writer
reader
reader
writer
reader
writer
reader
writer
reader
writer
reader
writer
reader
writer

1:
2:
3:
1:
2:
1:
2:
1:
3:
1:
3:
1:
2:
1:

start preparing data.


ready to read from register.
ready to read from register.
done writing to register [ v = 0x1].
reading from register [ reg = 0x1].
start preparing data.
ready to read from register.
done writing to register [ v = 0x2].
reading from register [ reg = 0x2].
start preparing data.
ready to read from register.
done writing to register [ v = 0x3].
reading from register [ reg = 0x3].
start preparing data.

See Also

How to Use the Semaphore Struct on page 1279

try_up() and try_down() on page 1283

set_value() and get_value() on page 1285

set_max_value() and get_max_value() on page 1286

23.8.4

try_up() and try_down()

Purpose
Synchronize producer and consumer methods

Category
Predefined method of the predefined semaphore struct

Syntax
semaphore.try_up(): bool
semaphore.try_down(): bool
Specman e Language Reference
1999-2015

1283
.

Product Version 15.1


All Rights Reserved.

Syntax Example
compute sem1.try_up();
compute sem1.try_down();

Parameters
semaphore

An expression of type semaphore or rdv_semaphore.

Description
The try_up() and try_down() methods try to increment or decrement the number of available resources
by 1, respectively. If the number of available resources is already at its maximum or minimum
respectively, these methods return immediately without any effect (in particular, no blocking). If the
number of resources was changed, the returned value is TRUE. If the number of resources was not
changed, the returned value is FALSE. The FIFO ordered of service of the semaphore is kept even when
the try_up() and try_down() methods are involved. For example, a try_up() will never succeed if there
are pending calls to up().
Note

Being regular methods (not TCMs), try_up() and try_down() never generate a context switch.

Example
The following example shows a driver that sends information at each clock. If there is valid data in reg
that is protected by the semaphore reg_sem, it sends its contents. Otherwise, it sends 0.
driver()@any is {
while TRUE {
if sem.try_down() {
send( reg );
} else {
send( 0 );
};
wait cycle;
};
};

See Also

How to Use the Semaphore Struct on page 1279

up() and down() on page 1279

set_value() and get_value() on page 1285

set_max_value() and get_max_value() on page 1286

Specman e Language Reference


1999-2015

1284

Product Version 15.1


All Rights Reserved.

23.8.5

set_value() and get_value()

Purpose
Set and get the number of available resources of a semaphore

Category
Predefined method of semaphore struct

Syntax
semaphore.set_value(new_value: int)
semaphore.get_value(): int
Syntax Example
sem1.set_value(7);
cur_value = sem1.get_value();

Parameters
new_value

An expression of type signed int

Description
The set_value() method sets the number of available resources of the semaphore. By default, a
semaphore is initialized with zero available resources.
The new value must be a non-negative integer, no larger than MAX_INT. If the set_max_value()
method of the struct was used, the new value must also be smaller or equal to the last setting of the
maximum number of resources. If these conditions do not hold, Specman issues a runtime error.
The set_value() method cannot be called if either up() or down() was previously called. In such case,
Specman issues an error. Setting the value of an rdv_semaphore to something other than zero also
results in a runtime error.
You must specify set_value(1) and set_max_value(1) in the post_generate() method, or you will get an
error when you use the set_value() method. For example:

Specman e Language Reference


1999-2015

1285
.

Product Version 15.1


All Rights Reserved.

post_generate() is also {
sem.set_max_value(1);
sem.set_value(1);
print sem.get_value();
};

The get_value() method returns the current number of available resources of the semaphore.

Example
<'
extend sys {
sem : semaphore;
run() is also {
sem.set_value(5);
print sem.get_value();
};
};
'>

Note If you are using a semaphore to implement locker functionality (Using Semaphores and
Lockers on page 1278), using set_value() within run() produces an error.

Result:
sem.get_value() = 5

See Also

How to Use the Semaphore Struct on page 1279

up() and down() on page 1279

try_up() and try_down() on page 1283

set_max_value() and get_max_value() on page 1286

23.8.6

set_max_value() and get_max_value()

Purpose
Set and get the maximum number of available resources of a semaphore

Category
Predefined method of semaphore struct
Specman e Language Reference
1999-2015

1286

Product Version 15.1


All Rights Reserved.

Syntax
semaphore.set_max_value(new_value: int)
semaphore.get_max_value(): int
Syntax Example
sem1.set_max_value(17);
cur_max_value = sem1.get_max_value();

Parameters
new_value

An expression of type signed int

Description
The set_max_value() method sets the maximum number of available resources of the semaphore. By
default, a semaphore is initialized with a maximum of MAX_INT available resources.
The new value must be a positive integer, no larger than MAX_INT. If set_value() was used, the new
value must not be smaller than the number of available resources. If these conditions do not hold,
Specman issues a runtime error.
The value of an rdv_semaphore is constantly zero. Therefore its default maximum value is zero, and it
cannot be set to a value other than that. Trying to do so also results in a runtime error.
set_max_value() cannot be called if either up() or down() was previously called. In such case, Specman
issues an error.
It is safer to invoke the set_max_value() method before any other semaphore method.
The get_max_value() method returns the current limit for available resources of the semaphore.

Example
<'
extend sys {
sem : semaphore;
run() is also {
sem.set_max_value(5);
print sem.get_max_value();
};
};
'>

Specman e Language Reference


1999-2015

1287
.

Product Version 15.1


All Rights Reserved.

Result:
sem.get_max_value() = 5

See Also

How to Use the Semaphore Struct on page 1279

up() and down() on page 1279

try_up() and try_down() on page 1283

set_value() and get_value() on page 1285

23.8.7

lock() and free()

Purpose
Control access to a shared resource

Category
Predefined TCM of locker struct

Syntax
locker-exp.lock()
locker-exp.free()
Syntax Example
lckr.lock();
lckr.free();

Parameters
locker-exp An expression of type locker.

Description
locker is a predefined struct with two predefined methods, lock() and free(). These methods are TCMs.
Once a field is declared to be of type locker, that field can be used to control the execution of TCMs by
making calls from the TCMs to locker.lock() and locker.free().
Specman e Language Reference
1999-2015

1288

Product Version 15.1


All Rights Reserved.

If you call locker-exp.lock() from multiple TCMs, the first TCM gets the lock and can continue
execution. The execution of the other TCMs is blocked. Thus any resources that are shared among the
TCMs will be available only to the TCM that gets the lock.
When a TCM calls free(), control goes to the next TCM serviced by the scheduler that is waiting on the
locker. The order in which the lock is granted is by a FIFO (First In First Out) order of client lock()
requests.
Specman uses non-pre-emptive scheduling, which means that thread execution is interrupted only when
the executing thread reaches a wait, sync, TCM call, free(), or lock() request. This has two implications:

You do not need to use locks unless the code to be executed between the lock() and the free() contains
a wait, sync, or TCM call.
Code that is not time-consuming and is used by multiple threads should be put in a regular method
so no locks are needed.

Notes

Calling lock() again before calling free() results in a deadlock. The TCM attempting to acquire the
locker stops and waits for the locker to be freed. This TCM never executes because it cannot free the
locker. Naturally none of the other TCMs that wait for the locker is executed.
The release of the locker must be explicit. If the locking thread ends (either normally or abnormally)
without a call to free(), the locker is not released. Again, none of the other TCMs that wait for the
locked is executed.
Note that the rerun() method does not release the locker. After rerun() is called, any remaining
lock requests remain in the locker structure.

See Also

Using Semaphores and Lockers on page 1278

Example 1
This example illustrates how the execution of two TCMs are controlled using a field of type locker.
<'
struct foo {
lckr: locker;
tcm1(id: uint) @sys.any is {
all of {
{
lckr.lock();
out("first branch got the lock");
wait [2];
Specman e Language Reference
1999-2015

1289
.

Product Version 15.1


All Rights Reserved.

out("first branch frees the lock");


lckr.free();
};
{
lckr.lock();
out("second branch got the lock");
wait [2];
out("second branch frees the lock");
lckr.free();
};
};
wait [10] * cycle;
out("******After 10 cycles*********");
stop_run();
};
tcm2() @sys.any is {
lckr.lock();
out("tcm2 got the lock");
wait [2] * cycle;
out("tcm2 frees the lock");
lckr.free();
};
run() is also {
start tcm2();
start tcm1(1);
};
};
extend sys {
foo_inst: foo;
};
'>

Result
Note that tcm2 gets the lock first, then the first all of branch of tcm1 and finally the last all of branch of
tcm1.
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
tcm2 got the lock
tcm2 frees the lock
first branch got the lock
first branch frees the lock
second branch got the lock
Specman e Language Reference
1999-2015

1290

Product Version 15.1


All Rights Reserved.

second branch frees the lock


******After 10 cycles*********
Last specman tick - stop_run() was called
Normal stop - stop_run() is completed
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

Example 2
<'
struct st {
lckr: locker;
ftcm(id: uint) @sys.any is {
for i from 0 to 2 do {
lckr.lock();
out("Id ", id, " got the resource");
wait cycle;
lckr.free();
};
};
run() is also {
start ftcm(1);
start ftcm(2);
};
};
extend sys {
sti: st;
};
'>

Result
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
Thread 1 got the resource
Thread 2 got the resource
Thread 1 got the resource
Thread 2 got the resource
Thread 1 got the resource
Thread 2 got the resource
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

Specman e Language Reference


1999-2015

1291
.

Product Version 15.1


All Rights Reserved.

23.9 Pseudo-Methods
A pseudo-method is a type of method unique to the e language. Pseudo-methods are e macros that look
like methods. They have the following characteristics:

Unlike methods, pseudo-methods are not restricted to structs.


They can be applied to any expression, including literal values, scalars, and compound arithmetic
expressions.
You can define your own pseudo-methods using define as on page 1085 or define as computed
Macro on page 1096.

You cannot change or extend pseudo-methods through the use of is only, is also or is first.

The Specman debugger does not recognize pseudo-methods.

The following sections provide descriptions of the pseudo-methods:

source_location() Pseudo-Method on page 1292

source_method() Pseudo-Method on page 1293

writef() Pseudo-Method on page 1294

as_a() on page 194

pack() on page 1059

unpack() on page 1064

swap() on page 1069

See Also

Chapter 25 List Pseudo-Methods

File Routines on page 1555

Chapter 27 Predefined Routines

23.9.1

source_location() Pseudo-Method

Purpose
Get source reference string

Category
Pseudo-method

Specman e Language Reference


1999-2015

1292

Product Version 15.1


All Rights Reserved.

Syntax
source_location(): string
Syntax Example
print source_location();

Description
Returns the source location string. The string describes the line number and the module name in which
the source_location() method was invoked. The format of the string is:
at line line-number in @module-name

Example
<'
extend sys {
m() is {
out("I'm ",source_location());
};
};
'>

Result
cmd-prompt> sys.m()
I'm at line 4 in @xxx

See Also

dut_error_struct on page 594

source_method() Pseudo-Method on page 1293

23.9.2

source_method() Pseudo-Method

Purpose
Get name of executing method

Specman e Language Reference


1999-2015

1293
.

Product Version 15.1


All Rights Reserved.

Category
Pseudo-method

Syntax
source_method(): string
Syntax Example
print source_method();

Description
Returns the name of the enclosing method. The string describes the line number and the module name in
which the source_method() method was invoked. The format of the string is:
method-name at line line-number in @module-name

Example
<'
extend sys {
run() is also {
out("location = '", source_location(), "'\nmethod = '", source_method(), "'");
};
};
'>

Result
cmd-prompt> run
location = 'at line 4 in @method'
method = 'sys.run()
at line 3 in @method'

See Also

source_location() Pseudo-Method on page 1292

23.9.3

writef() Pseudo-Method

Purpose
Write to a file in a specified format, with no new line at the end
Specman e Language Reference
1999-2015

1294

Product Version 15.1


All Rights Reserved.

Category
Pseudo-method

Syntax
writef(output_file: file-descriptor, format: string, item: exp, ...)
Syntax Example
var m_file: file = files.open("a_f.txt", "w", "My data");
var m_i := new m_struct_s;
writef(m_file, "Type: %s\tData: %s\n", m_i.s_type, m_i.data);

Parameters
file

The file descriptor of the file to write into.

format

A string containing a standard C formatting mask for each item. See Format String on
page 1528 for information about formatting masks.

item

An e expression to write to the file.

Description
Adds a formatted string to the end of the specified file. No newline is automatically added. (Use \n in
the formatting mask to add a newline).
The file must already have been opened with open() on page 1561, otherwise an error is issued.
If the number of items in the formatting mask is different than the number of item expressions, an error
is issued.
How the data is written to the file is affected by the open() mode w or a option and by whether or
not the file already exists, as follows:

If the file did not previously exist and the w (write) option is used with open(), then writef() writes
the data into a new file.
If the file did not previously exist and the a (append) option is used with open(), then no data is
written.
If the file did previously exist and the w (write) option is used with open(), then writef() overwrites
the contents of the file.
If the file did previously exist and the a (append) option is used with open(), then writef() appends
the data to the existing contents of the file.

Specman e Language Reference


1999-2015

1295
.

Product Version 15.1


All Rights Reserved.

Example
In the following example, a file named pkts_file.txt is opened in write (w) mode, with file descriptor
mypkts. The writef() pseudo-method writes the contents of a list of pkt_s structs to the pkts_file, using
a new line (\n) for each struct instance, with tabs (\t) after the struct instance name and the ptype field.
The struct instance and the ptype are written as strings (%s) and pdata is written as a number (%d).
type pkt_t: [PKT1, PKT2, PKT3];
struct pkt_s {
ptype: pkt_t;
pdata: byte;
};
extend sys {
pkt_l[5]: list of pkt_s;
run() is also {
var mypkts: file = files.open("pkts_file.txt", "w", "");
for each (pkt) in pkt_l {
writef(mypkts, "Struct: %s\tType: %s\tData: %d\n",
pkt, pkt.ptype, pkt.pdata);
};
files.close(mypkts);
};
};

Result
This is what the contents of the pkts_file.txt file look like:
Struct:
Struct:
Struct:
Struct:
Struct:

pkt_s-@0
pkt_s-@1
pkt_s-@2
pkt_s-@3
pkt_s-@4

Type:
Type:
Type:
Type:
Type:

PKT2
PKT3
PKT3
PKT2
PKT1

Data:
Data:
Data:
Data:
Data:

148
198
61
18
82

See Also

close() on page 1557

open() on page 1561

write() on page 1568

write_lob() on page 1569

Format String on page 1528

Specman e Language Reference


1999-2015

1296

Product Version 15.1


All Rights Reserved.

23.10 Time Conversion Pseudo-Methods


The following pseudo-methods are useful for manipulating expressions of type time:

to_specman_scale() Pseudo-Method on page 1297

from_specman_scale() Pseudo-Method on page 1300

to_specman_scale_trunc() Pseudo-Method on page 1302

from_specman_scale_trunc() Pseudo-Method on page 1303

to_real_specman_scale() Pseudo-Method on page 1304

from_real_specman_scale Pseudo-Method on page 1306

double_to_specman_scale() Pseudo-Method on page 1307

double_from_specman_scale() Pseudo-Method on page 1309

See Also

Pseudo-Methods on page 1292

23.10.1 to_specman_scale() Pseudo-Method


Purpose
Convert a time expression to the Specman timescale

Category
Pseudo-method

Syntax
to_specman_scale(exp: time, unit: time-unit-designator): time
Syntax Example
wait delay(to_specman_scale(clock_period, ns));

Parameters
exp

An expression of type time. (Expressions of type uint or int are automatically converted to
type time.)

Specman e Language Reference


1999-2015

1297
.

Product Version 15.1


All Rights Reserved.

unit

One of the time unit designators defined by the enumerated type e_time_units: fs, ps, ns, us,
ms, sec, min, hr. This designator specifies the time unit of the expression to be converted.

Description
Converts an expression from the specified timescale to the Specman timescale and returns the result as
an expression of type time. This method is useful to convert expressions into the appropriate timescale
for the simulator. For example, you can define delay expressions independent of timescale or simulator
and use this method to convert the expression to the appropriate timescale.

Note

If the Specman timescale does not have sufficient precision for the scaling operation, this method
returns 0.

Example 1
This example shows how you can specify a delay in nanoseconds, regardless of what the Specman
timescale is.

top.v
`timescale 1ps/1ps
module top;
reg clk;
initial clk = 1;
always clk = #500 ~clk;
endmodule

top1.e
<'
verilog time 1ps/1ps;
extend sys {
clock_period : uint;
keep clock_period == 1;
event clk is rise('top.clk');
write() @clk is {
wait delay(to_specman_scale(clock_period, ns));
print sys.time;
stop_run();
};
run() is also {
Specman e Language Reference
1999-2015

1298

Product Version 15.1


All Rights Reserved.

start write();
};
};
'>

Results
sys.time = 2000

Example 2
This example has similar results to Example 1 on page 1298, except that a field of type time is used,
instead of a field of type uint. In this approach, to_specman_scale() is not required because the
conversion is performed implicitly when the field clock_period is generated as 1 ns.

top.e
<'
verilog time 1ps/1ps;
extend sys {
clock_period : time;
keep clock_period == 1 ns;
event clk is rise('top.clk');
write() @clk is {
wait delay(clock_period);
print sys.time;
stop_run();
};
run() is also {
start write();
};
};
'>

Results
sys.time = 2000

See Also

from_specman_scale() Pseudo-Method on page 1300

Specman e Language Reference


1999-2015

1299
.

Product Version 15.1


All Rights Reserved.

23.10.2 from_specman_scale() Pseudo-Method


Purpose
Convert a time expression to a specified timescale

Category
Pseudo-method

Syntax
from_specman_scale(exp: time, unit: time-unit-designator): time
Syntax Example
out("Time ", from_specman_scale(sys.time,fs));

Parameters
exp

An expression of type time. (Expressions of type uint or int are automatically converted to
type time.)

unit

One of the time unit designators defined by the enumerated type e_time_units: fs, ps, ns,
us, ms, sec, min, hr. This designator specifies the timescale of the returned value.

Description
Converts an expression of type time from the Specman timescale to the specified timescale and returns
the result as an expression of type time. You can use this method to print and display values consistently,
regardless of what Specman timescale is used in other parts of the verification environment.

Notes

The result returned by from_specman_scale() is a 64-bit integer (without an attached time unit) and
should be used for arithmetical calculations. When used, this value will be assumed to have Specman
time units. For example, if the result returned by from_specman_scale() is 10 and the Specman
simulation unit is 1ps, the command print sys.time using scale = simdef results in 10ps.
If the Specman timescale does not have sufficient precision for the scaling operation, this method
returns 0.

Specman e Language Reference


1999-2015

1300

Product Version 15.1


All Rights Reserved.

Example 1
<'
verilog time 1ns/1ps; -- defines the Specman timescale
extend sys {
run() is also {
out("Time ", from_specman_scale(sys.time,fs));
};
};
'>

Results
Assuming sys.time is 10, the above call to out() prints:
Time 10000000

Example 2
The following code prints the variable delay in nanoseconds, regardless of what the Specman
timescale is.
<'
verilog time 1ps/1ps; -- defines the Specman timescale
extend sys {
clock_period: time;
keep clock_period == 2 ns;
run() is also {
out("Duty cycle is ", from_specman_scale(clock_period/2,ns));
};
};
'>

Results
Duty cycle is 1

See Also

to_specman_scale() Pseudo-Method on page 1297

Specman e Language Reference


1999-2015

1301
.

Product Version 15.1


All Rights Reserved.

23.10.3 to_specman_scale_trunc() Pseudo-Method


Purpose
Convert a time expression to the Specman timescale and return a boolean value indicating whether a
truncation took place.

Category
Pseudo-method

Syntax
to_specman_scale_trunc(exp: time, unit: time-unit-designator, res: * time): bool

Syntax Example
t : time;
if (to_specman_scale_trunc(10,ps,t) == FALSE) {
print t;
};

Parameters
exp

An expression of type time. (Expressions of type uint or int are automatically converted to
type time.)

unit

One of the time unit designators defined by the enumerated type e_time_units: fs, ps, ns,
us, ms, sec, min, hr. This designator specifies the timescale of the returned value.

res

A variable of type time, where the converted value is returned.

Description
Converts an expression from the specified timescale to the Specman timescale, and returns the result as
an expression of type time in res. This method is useful for converting expressions into the appropriate
timescale for the simulator. The return resultTRUE or FALSEreflects whether the result expression
was truncated.
Note

Unlike to_specman_scale(), a warning message about truncation is not printed.

Specman e Language Reference


1999-2015

1302

Product Version 15.1


All Rights Reserved.

Example
t: time;
if (to_specman_scale_trunc(10, ps, t) == FALSE) {
print t;
};

Results
Assuming simulation time is 10 ns, the above example converts the result time to ps. If the result was not
truncated, it prints the converted time value.

23.10.4 from_specman_scale_trunc() Pseudo-Method


Purpose
Convert a time expression to a specified timescale and return a boolean value indicating whether a
truncation took place.

Category
Pseudo-method

Syntax
from_specman_scale_trunc(exp: time, unit: time-unit-designator, res: * time): bool

Parameters
exp

An expression of type time. (Expressions of type uint or int are automatically converted to
type time.)

unit

One of the time unit designators defined by the enumerated type e_time_units: fs, ps, ns,
us, ms, sec, min, hr. This designator specifies the timescale of the returned value.

res

A variable of type time, where the converted value is returned.

Description
Converts an expression of type time from the Specman timescale to the specified timescale, and returns
the result is an expression of type time in res. The return resultTRUE or FALSEindicates whether
the result expression was truncated.
Specman e Language Reference
1999-2015

1303
.

Product Version 15.1


All Rights Reserved.

Note

Unlike from_specman_scale(), a warning message about truncation is not printed.

Example
<'
verilog time 1ps/1ps; -- defines the Specman timescale
extend sys {
run() is also {
var t : time;
if (from_specman_scale_trunc(sys.time,ns,t) == FLASE) {
print t;
} else {
out("Result was truncated");
};
};
'>

Results
Assuming sys.time is 10 ps, the above example truncates the result time to 0, and returns TRUE.

23.10.5 to_real_specman_scale() Pseudo-Method


Purpose
Convert a time expression to the Specman timescale, and returns the result as real (nothing is truncated)

Category
Pseudo-method

Syntax
to_real_specman_scale(exp: time, unit: time-unit-designator): real

Syntax Example
t : time;
if (to_specman_scale_trunc(2,fs,t) == TRUE) {
print to_real_specman_scale(2,fs);
};

Specman e Language Reference


1999-2015

1304

Product Version 15.1


All Rights Reserved.

Parameters
exp

An expression of type time. (Expressions of type uint or int are automatically converted to
type time.)

unit

One of the time unit designators defined by the enumerated type e_time_units: fs, ps, ns,
us, ms, sec, min, hr. This designator specifies the timescale of the returned value.

Description
Converts an expression from the specified timescale to the Specman timescale, and returns the result as
an expression of type real. This method is useful to convert expressions that are otherwise truncated.

Example
This example shows how to use to_real_specman_scale() to avoid truncation.
/// top.v
`timescale 1ps/1ps
module top;
reg clk;
initial clk = 1;
always clk = #500 ~clk;
endmodule
/// top1.e
<'
verilog time 1ps/1ps;
extend sys {
write() @sys.any is {
t : time;
if (to_specman_scale_trunc(2,fs,t) == TRUE) {
print to_real_specman_scale(2,fs);
};
stop_run();
};
run() is also {
start write();
};
};
'>

Specman e Language Reference


1999-2015

1305
.

Product Version 15.1


All Rights Reserved.

Results
If to_specman_scale() is used, the result is truncated to 0. However, with to_real_specman_scale(), the
result is .002.

23.10.6 from_real_specman_scale Pseudo-Method


Purpose
Convert a real expression to a specified timescale, and return a time expression.

Category
Pseudo-method

Syntax
from_real_specman_scale(exp : real, units: e_time_units) : time

Syntax Example
out("Time ", from_real_specman_scale(0.002,fs));

Parameters
exp

An expression of type real.

unit

One of the time unit designators defined by the enumerated type e_time_units: fs, ps, ns,
us, ms, sec, min, hr. This designator specifies the timescale of the returned value.

Description
Converts an expression of type real from the Specman timescale to the specified timescale, and returns
the result is an expression of type time.

Notes

This method is the inverse operation of to_real_specman_scale().

Specman e Language Reference


1999-2015

1306

Product Version 15.1


All Rights Reserved.

The result returned by from_real_specman_scale() is a real number (without an attached time unit)
and should be used for arithmetical calculations. When used, this value will be assumed to have
Specman time units. For example, if the result returned by from_specman_scale() is 10.5 and the
Specman simulation unit is 1ps, the command print sys.time using scale = simdef results in 10.5ps.

Example
<'
verilog time 1ps/1ps; -- defines the Specman timescale
extend sys {
run() is also {
out (from_real_specman_scale(0.002,fs));
};
'>

Results
0.002 ps in fs time units results in 2.

23.10.7 double_to_specman_scale() Pseudo-Method


Purpose
Convert a real expression to the Specman timescale and return a real expression.

Category
Pseudo-method

Syntax
double_to_specman_scale(exp: real, unit: time-unit-designator, res: *time): real

Syntax Example
wait delay(double_to_specman_scale(1.23,ns));

Parameters
exp

An expression of type time.

Specman e Language Reference


1999-2015

1307
.

Product Version 15.1


All Rights Reserved.

unit

One of the time unit designators defined by the enumerated type e_time_units: fs, ps, ns,
us, ms, sec, min, hr. This designator specifies the timescale of the returned value.

res

A variable of type time, where the converted value is returned.

Description
Converts a type real expression from the specified timescale to the Specman timescale, and returns the
result as an expression of type real.

Example
/// top.v
`timescale 1ns/1ps
module top;
reg clk;
initial clk = 1;
always clk = #500 ~clk;
endmodule
/// top1.e
<'
extend sys {
write() @sys.any is {
wait delay(double_to_specman_scale(0.5, us));
set_config(print, scale, ns);
print sys.time;
stop_run();
};
run() is also {
start write();
};
};
'>

This example specifies a delay in ns, regardless of the Specman timescale.

Result
Delay of .05 us is: 500 ns

Specman e Language Reference


1999-2015

1308

Product Version 15.1


All Rights Reserved.

23.10.8 double_from_specman_scale() Pseudo-Method


Purpose
Convert a real expression to a specified timescale return value is also real expression.

Category
Pseudo-method

Syntax
double_from_specman_scale(exp: real, unit: time-unit-designator): real

Syntax Example
out("Time ", double_from_specman_scale(1.23,fs));

Parameters
exp

An expression of type real.

unit

One of the time unit designators defined by the enumerated type e_time_units: fs, ps, ns,
us, ms, sec, min, hr. This designator specifies the timescale of the returned value.

Description
Converts an expression of type real from the Specman timescale to the specified timescale, and returns
the result as an expression of real.
Note The result returned by double_from_real_specman_scale() is a real number (without an
attached time unit) and should be used for arithmetical calculations. When used, this value will be
assumed to have Specman time units. For example, if the result returned by from_specman_scale() is
10.5 and the Specman simulation unit is 1ps, the command print sys.time using scale = simdef results
in 10.5ps.

Example
<'
verilog time 1ns/1ps; -- defines the Specman timescale
extend sys {
run() is also {
Specman e Language Reference
1999-2015

1309
.

Product Version 15.1


All Rights Reserved.

out("Time ", double_from_specman_scale(1.2345,ps));


};
};
'>

Result
The above call to out() prints the follwing:
Time 1234.5

Specman e Language Reference


1999-2015

1310

Product Version 15.1


All Rights Reserved.

24

Importing e Files

Imports (import statement, verilog import statement) load a given e file or Verilog file This chapter
describes the import statement.

See Also

File Structure on page 34

verilog import on page 840

24.1 import
Purpose
Load other e modules

Category
Statement

Syntax
import file-name, ... | ( file-name, ... )
Syntax Example
import test_drv.e;

Specman e Language Reference


1999-2015

1311
.

Product Version 15.1


All Rights Reserved.

Parameters
file-name, ...

The names of files, separated by commas, that contain e modules to be imported. If no


extension is given for a file name, an .e extension is assumed.
The (file-name, ...) syntax is for cyclic importing, in which one module references a
field in a second module, and the second module references a field in the first module.
File names can contain references to environment variables using the UNIX notation
$name or ${name}.
Relative path indicators ./ and ../ can be used in filenames.

Description
Loads additional e modules before continuing to load the current file.
If a specified module has already been loaded or compiled, the statement is ignored. For modules not
already loaded or compiled, the search sequence is:
1.

The current directory.

2.

Directories specified by the SPECMAN_PATH environment variable.

3.

The directory in which the importing module resides.

If you need to refer in struct A to a struct member of struct B, and you also need to refer in struct B to a
struct member of struct A, that is called a cyclic reference. The import statement can handle cyclic
references if you do the following:
1.

Before the definition of struct A in module A, add an import of module B in which struct B is
defined.

2.

Before the definition of struct B in module B, add an import of module A.

This is called implicit cyclic importing.


Another way to do a cyclic import is to use the import ( file-name, ... ) syntax, which resolves cycles by
loading the two or more modules as one.
When multiple modules are loaded together, the behavior is as if the files are concatenated.
No module is imported more than once. If an import statement includes a module that has already been
loaded, that module is not imported.

Specman e Language Reference


1999-2015

1312

Product Version 15.1


All Rights Reserved.

Notes

Within a given e module, import statements must appear before any other statements except
preprocessor directives (#ifdef, #ifndef, #define, and #undef statements), verilog import
statements, and package statements.
You cannot import modules that reside in different directories but have the same base names, even
if they have different extensions. This is because Specman internally uses only the base name, without
its extension.
If you do not enter at least one file name after the import keyword, a load or compile-time error is
issued.
Cyclic importing requires more memory to load multiple modules together than it takes to import
modules singly, and it takes longer, which delays the automatic consistency checking of the e code.
Cyclic importing can also mask problems with the ability of a module to be used standalone, in future
applications, due to one module relying on another module being loaded.
Attention must be given to the import order in implicit cyclic importing just as it is in non-cyclic
importing. You cannot reference or extend a struct before it is defined. If module A imports module
B, and if you do load A from the command line or import A from another module, the body of
module B is parsed before module A. However, if you use explicit cyclic importing, import (A, B),
then the body of module A is parsed before module B is imported.

Example 1
The following UNIX commands are executed prior to starting Specman and loading the e module shown
below:
setenv S_PATH /specman/top
cd /cad/test

All of the import statements in the following e module are legal:


import
//
//
import
//
import
//
import
//
import
//

t_fil_1.e;
Load /cad/test/t_fil_1.e if it exists, otherwise load
$SPECMAN_PATH/t_fil_1.e
./t_fil_2.e;
Load /cad/test/t_fil_2.e (relative path)
../t_fil_3.e;
Load /cad/t_fil_3.e (relative path)
/cad/test/t_fil_4.e;
Load /cad/test/t_fil_4.e (absolute path)
$S_PATH/t_fil_5.e;
Load /specman/top/t_fil_5.e

Specman e Language Reference


1999-2015

1313
.

Product Version 15.1


All Rights Reserved.

Example 2
In the following example, a struct named pci_transaction is defined in one module, which is then
imported into another module where additional fields and constraints are added in an extension to the
struct definition.
<'
// module pci_transaction_definition.e
type PCICommandType: [ IO_READ=0x2, IO_WRITE=0x3,
MEM_READ=0x6, MEM_WRITE=0x7 ];
struct pci_transaction {
address: uint;
command: PCICommandType;
bus_id: uint;
};
'>
-----------------------------------------------------------<'
// module pci_transaction_extension.e
import pci_transaction_definition;
extend pci_transaction {
data: list of uint;
num_data_phases: uint;
keep num_data_phases in [0..7];
keep data.size() == num_data_phases;
};
'>

Example 3
In the following example, three modules are involved in cyclic referencing:

the switch.e module references the packet struct definition in the packet.e module

the packet.e module references the cell struct definition in the cell.e module

the cell.e module references the switch struct definition in the switch.e module.

You only need to load the switch.e module into Specman. The switch.e module imports the packet.e
module, which imports the cell.e module. Then the cell.e module imports the switch.e module,
completing the cycle. This is implicit cyclic importing, since each import statement imports only one of
the other modules.
<'
// module switch.e - needs packet.e for the list of packet
import packet;
struct switch {
packets: list of packet;
Specman e Language Reference
1999-2015

1314

Product Version 15.1


All Rights Reserved.

};
'>
-----------------------------------------------------------<'
// module packet.e - needs cell.e for the list of cell
import cell;
struct packet {
!cells: list of cell;
len: uint;
};
'>
-----------------------------------------------------------<'
// module cell.e - needs switch.e for the switch definition
import switch;
struct cell {
parent: switch;
data[20]: list of byte;
};
'>

Example 4
This example shows the explicit cyclic import syntax, import (file-name, ...), using the same modules as
Example 3 on page 1314. All three of the modules involved in the cyclic referencing are imported by
one import statement in a fourth module named top_imp.e. You only need to load the top_imp.e module
into Specman.
<'
// module top_imp.e
import (switch, packet, cell);
'>
-----------------------------------------------------------<'
// module switch.e - needs packet.e for the list of packet
struct switch {
packets: list of packet;
};
'>
-----------------------------------------------------------<'
// module packet.e - needs cell.e for the list of cell
struct packet {
!cells: list of cell;
len: uint;
};

Specman e Language Reference


1999-2015

1315
.

Product Version 15.1


All Rights Reserved.

'>
-----------------------------------------------------------<'
// module cell.e - needs switch.e for the switch definition
struct cell {
parent: switch;
data[20]: list of byte;
};
'>

Example 5
This example shows how to load the files in Example 3 on page 1314 while avoiding the loss of
modularity that results from cyclic importing.
In Example 3, the cell.e module relies on a type (switch) that is defined in the switch.e module. This
means that a cell struct cannot be used without also using a switch struct, so that cell.e cannot stand
alone.
In this example, the switch struct instance has been moved from the cell.e module to an extension of cell
in the switch.e module, so that the cell.e module does not rely on the presence of the switch.e module.
<'
// module switch.e - needs packet.e for the list of packet
import packet;
struct switch {
packets: list of packet;
};
extend cell {
parent: switch;
};
'>
-----------------------------------------------------------<'
// module packet.e - needs cell.e for the list of cell
import cell;
struct packet {
!cells: list of cell;
len: uint;
};
'>
-----------------------------------------------------------<'
// module cell.e
struct cell {
data[20]: list of byte;
};
Specman e Language Reference
1999-2015

1316

Product Version 15.1


All Rights Reserved.

'>

See Also

#define on page 1130

#ifdef, #ifndef on page 1127

verilog import on page 840

Specman e Language Reference


1999-2015

1317
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

1318

Product Version 15.1


All Rights Reserved.

25

List Pseudo-Methods

This chapter describes pseudo-methods used to work with lists. It contains the following sections:

Pseudo-Methods Overview on page 1319

Using List Pseudo-Methods on page 1320

Pseudo-Methods to Modify Lists on page 1320

General List Pseudo-Methods on page 1349

Sublist Pseudo-Methods on page 1400

Math and Logic Pseudo-Methods on page 1407

List CRC Pseudo-Methods on page 1417

Keyed List Pseudo-Methods on page 1423

See Also

Chapter 26 Set Pseudo-Methods

25.1 Pseudo-Methods Overview


A pseudo-method is a type of method unique to the e language. Pseudo-methods are e macros that look
like methods. They have the following characteristics:

Unlike methods, pseudo-methods are not restricted to structs.


They can be applied to any expression, including literal values, scalars, and compound arithmetic
expressions.

You cannot change or extend pseudo-methods through the use of is only, is also or is first.

The Specman debugger does not recognize pseudo-methods.

List pseudo-methods are associated with list data types, as opposed to being within the scope of a struct.
Specman e Language Reference
1999-2015

1319
.

Product Version 15.1


All Rights Reserved.

See Also

e Data Types on page 137

list-method() on page 121

in on page 96

Chapter 23 Predefined Methods

25.2 Using List Pseudo-Methods


Once a list field or variable has been declared, you can operate on it with a list pseudo-method by
attaching the pseudo-method name, preceded by a period, to the list name. Any parameters required by
the pseudo-method go in parentheses after the pseudo-method name.
Many of the list pseudo-methods take expressions as parameters and operate on every item in the list.
For example, the following calls the apply() pseudo-method for the list named p_list, with the
expression .length + 2 as a parameter. The pseudo-method returns a list of numbers found by adding 2
to the length field value in each item in the list.
n_list = p_list.apply(.length + 2);

It is important to put a period (.) in front of field names being accessed by pseudo-methods, as in
.length +2, above.
In pseudo-methods that take expressions as parameters, the it variable can be used in the expression to
refer to the current list item, and the index variable can be used to refer to the current items list index
number. You can omit it from the expression. That is, it.field is syntactically the same as .field.
Pseudo-methods that return values can only be used in expressions.

See Also

Pseudo-Methods Overview on page 1319

e Data Types on page 137

list-method() on page 121

25.3 Pseudo-Methods to Modify Lists


This section describes the pseudo-methods that change one or more items in a list.
The pseudo-methods in this section are:

add(item) on page 1321

Specman e Language Reference


1999-2015

1320

Product Version 15.1


All Rights Reserved.

add(list) on page 1323

add0(item) on page 1325

add0(list) on page 1327

clear() on page 1329

delete() on page 1330

fast_delete() on page 1332

insert(index, item) on page 1334

insert(index, list) on page 1335

pop() on page 1337

pop0() on page 1338

push() on page 1339

push0() on page 1341

resize() on page 1342

See Also

Pseudo-Methods Overview on page 1319

Using List Pseudo-Methods on page 1320

25.3.1

add(item)

Purpose
Add an item to the end of a list

Category
Pseudo-method

Syntax
list.add(item: list-type)
Syntax Example
var i_list: list of int;
i_list.add(5);

Specman e Language Reference


1999-2015

1321
.

Product Version 15.1


All Rights Reserved.

Parameters
list

A list.

item

An item of the same type as the list type, which is to be added to the list. The item is added at
index list.size(). That is, if the list contains five items, the last item is at index list.size() - 1, or 4.
Adding an item to this list places it at index 5.

Description
Adds the item to the end of the list.
Notes

For multi-dimensional lists, the item:

Must be a sublist with one dimension less than the main list

The basic type of the sublist must be the same as the basic type of the main list.

In other words, in the expression md-list1.add(md-list2), md-list2 must have one dimension less
than md-list1 and its basic type must be the same as the basic type for md-list1.

If the item is a struct or a list, a pointer to the list or struct instance is simply added to the list. (For
information about creating new structs, use the new, gen, copy(), deep_copy(), and unpack() links
in the See Also list below.)

Example 1
The following adds 2 to the end of the list named i_list (that is, to index position 3).
var i_list: list of int = {3; 4; 6};
i_list.add(2);

Result
print i_list
i_list =
0.
3
1.
4
2.
6
3.
2

Example 2
The following generates an instance of a packet struct and adds it to the list of packets named p_lst.
Specman e Language Reference
1999-2015

1322

Product Version 15.1


All Rights Reserved.

struct p_l {
!packet_i: packet;
!p_lst: list of packet;
mk_lst()@sys.clk is {
gen packet_i;
p_lst.add(packet_i);
stop_run();
};
};

See Also

new on page 125

gen...keeping on page 653

The copy() Method of any_struct or any_unit on page 1178

deep_copy() on page 1458

unpack() on page 1064

add(list) on page 1323

add0(item) on page 1325

add0(list) on page 1327

insert(index, item) on page 1334

insert(index, list) on page 1335

push() on page 1339

push0() on page 1341

resize() on page 1342

25.3.2

add(list)

Purpose
Add a list to the end of another list

Category
Pseudo-method

Specman e Language Reference


1999-2015

1323
.

Product Version 15.1


All Rights Reserved.

Syntax
list_1.add(list_2: list)
Syntax Example
i_list.add(l_list);

Parameters
list_1

A list.

list_2

A list of the same type as list_1, which is to be added to the end of list_1. The list is added at
index list.size(). That is, if the list contains five lists, the last list is at index list.size() - 1, or 4.
Adding a list to this list places it at index 5.

Description
Adds list_2 to the end of list_1.
The rules for using list_1.add(list_2) with multi-dimensional lists are as follows:

The number of dimensions of list_2 must either equal the number of dimensions of list_1 or be one
less than the number of dimensions of list_1.
The basic element type of list_2 must be exactly the same as the basic element type for list_1.

This is illustrated in the following example:


var md_list1: list of list
var md_list2: list of list
var md_list3: list of list
var md_list4: list of int;
var md_list5: list of list
var i: int;
md_list1.add(md_list2); //
md_list1.add(i);
//
md_list1.add(md_list3); //
md_list3.add(md_list4); //
md_list1.add(md_list5); //

of list of int;
of real;
of int;
of list of int;
Fails--The list types are incompatible.
Fails--The added item is not a list.
Succeeds.
Succeeds.
Succeeds.

Example 1
The following adds blue, green, and red to the list named colors_1.
<'
type color: [blue, green, yellow, orange, red];
Specman e Language Reference
1999-2015

1324

Product Version 15.1


All Rights Reserved.

extend sys {
run() is also {
var colors_1: list of color = {red; red; blue};
var colors_2: list of color = {blue; green; red};
colors_1.add(colors_2);
print colors_1;
};
};
'>

Example 2
The following example adds the literal list {blue; green; red} to the list named colors_3. The
colors_3 list then contains red, red, blue, blue, green, red.
var colors_3 := {"red"; "red"; "blue"};
colors_3.add({"blue"; "green"; "red"});

See Also

add(item) on page 1321

add0(item) on page 1325

add0(list) on page 1327

insert(index, item) on page 1334

insert(index, list) on page 1335

push() on page 1339

push0() on page 1341

resize() on page 1342

25.3.3

add0(item)

Purpose
Add an item to the head of a list

Category
Pseudo-method

Specman e Language Reference


1999-2015

1325
.

Product Version 15.1


All Rights Reserved.

Syntax
list.add0(item: list-type)
Syntax Example
var l_list: list of int = {4; 6; 8};
l_list.add0(2);

Parameters
list

A list.

item

An item of the same type as the list items, which is to be added to the head of the list.

Description
Adds the item to an existing list. The item is placed at the head of the existing list, as the first position
(that is, at index 0). All subsequent items are then reindexed by incrementing their old index by one.
Notes

For multi-dimensional lists, the item:

Must be a sublist with one dimension less than the main list

The basic type of the sublist must be the same as the basic type of the main list.

In other words, in the expression md-list1.add0(md-list2), md-list2 must have one dimension less
than md-list1 and its basic type must be the same as the basic type for md-list1.

If the item is a struct or a list, a pointer to the list or struct instance is simply added to the list. (For
information about creating new structs, use the new, gen, copy(), deep_copy(), and unpack() links
in the See Also list below.)

Example
The following example adds 1 to the beginning of the list named i_list. The i_list then contains 1, 1,
2, 3, 4, 5.
var i_list: list of int = {1;2;3;4;5};
i_list.add0(1);

See Also

new on page 125

gen...keeping on page 653

Specman e Language Reference


1999-2015

1326

Product Version 15.1


All Rights Reserved.

The copy() Method of any_struct or any_unit on page 1178

deep_copy() on page 1458

unpack() on page 1064

add(item) on page 1321

add(list) on page 1323

add0(list) on page 1327

insert(index, item) on page 1334

insert(index, list) on page 1335

push() on page 1339

push0() on page 1341

resize() on page 1342

25.3.4

add0(list)

Purpose
Add a list to the head of another list

Category
Pseudo-method

Syntax
list_1.add0(list_2: list)
Syntax Example
var i_list: list of int = {1; 3; 5};
var l_list: list of int = {2; 4; 6};
i_list.add0(l_list);

Parameters
list_1

A list.

list_2

A list of the same type as list_1, which is to be added to the beginning of list_1 (at list_1
index 0)

Specman e Language Reference


1999-2015

1327
.

Product Version 15.1


All Rights Reserved.

Description
Adds a new list to an existing list. The list_2 list is placed at the head of the existing list_1 list, starting
at the first list_1 index. All subsequent items are then reindexed by incrementing their old index by the
size of the new list being added.
The rules for using list_1.add0(list_2) when the lists are multi-dimensional are as follows:

The number of dimensions of list_2 must either equal the number of dimensions of list_1 or be one
less than the number of dimensions of list_1.
The basic element type of list_2 must be exactly the same as the basic element type for list_1.

This is illustrated in the following example:


var md_list1: list of list of list of int;
var md_list2: list of list of real;
var md_list3: list of list of int;
var md_list4: list of int;
var md_list5: list of list of list of int;
var i: int;
md_list1.add0(md_list2); // Fails--The list types are incompatible.
md_list1.add0(i);
// Fails--The added item is not a list.
md_list1.add0(md_list3); // Succeeds.
md_list3.add0(md_list4); // Succeeds.
md_list1.add0(md_list5); // Succeeds.

Example
The following adds 1, 2, 3, and 4 to the beginning of the list named b_list. The b_list then contains
1, 2, 3, 4, 5, 6.
var a_list: list of int = {1;2;3;4};
var b_list: list of int = {5;6};
b_list.add0(a_list);

Note
b_list.add0(a) returns the same result as a_list.add(b) in the above example, except that in the example,
b_list is added into a_list, while b_list.add0(a) adds a_list into b_list.

See Also

add(item) on page 1321

add(list) on page 1323

Specman e Language Reference


1999-2015

1328

Product Version 15.1


All Rights Reserved.

add0(item) on page 1325

insert(index, item) on page 1334

insert(index, list) on page 1335

push() on page 1339

push0() on page 1341

resize() on page 1342

25.3.5

clear()

Purpose
Delete all items from a list

Category
Pseudo-method

Syntax
list.clear()
Syntax Example
a_list.clear();

Parameters
list

A list.

Return Value
None

Description
Deletes all items in the list.

Specman e Language Reference


1999-2015

1329
.

Product Version 15.1


All Rights Reserved.

Example
The following removes all items from the list named l_list.
l_list.clear();

See Also

delete() on page 1330

fast_delete() on page 1332

resize() on page 1342

pop() on page 1337

pop0() on page 1338

25.3.6

delete()

Purpose
Delete an item from a list

Category
Pseudo-method

Syntax
list.delete(index: int)
Syntax Example
var l_list: list of int = {2; 4; 6; 8};
l_list.delete(2);

Parameters
list

A list.

index

The index of the item that is to be deleted from the list.

Specman e Language Reference


1999-2015

1330

Product Version 15.1


All Rights Reserved.

Description
Removes item number index from list (indexes start counting from 0). The indexes of the remaining
items are adjusted to keep the numbering correct.
If the index does not exist in the list, an error is issued.
Note In a keyed list, if two or more list items have the same key, the results of using list
pseudo-methods are unpredictable. See Keyed List Pseudo-Methods on page 1423.

Example 1
The following deletes 7 from index position 1 in the list named y_list. The list then consists of 5
(index 0) and 9 (index 1).
var y_list := {5; 7; 9};
y_list.delete(1);

Example 2
Since list.delete() only accepts a single item as its argument, you cannot use it to delete a range of items
in one call. This example shows a way to do that.
The following shows a user-defined method named del_range() which, given a list, a from value, and a
to value, produces a new list (with the same name) of the items in the previous list, minus the items with
indexes in the given range. If the range of values is not legal for the given list, the method fails with an
error message.
<'
extend sys {
my_list: list of byte;
keep my_list.size() == 20;
del_range(in_l:list of byte,from:int,to:int):list of byte is {
result.add(in_l[..from-1]);
result.add(in_l[to+1..]);
};
post_generate() is also {
my_list = del_range(my_list,5,15);
};
};
'>

Specman e Language Reference


1999-2015

1331
.

Product Version 15.1


All Rights Reserved.

See Also

clear() on page 1329

fast_delete() on page 1332

pop() on page 1337

pop0() on page 1338

resize() on page 1342

first_index() on page 1363

get_indices() on page 1366

last_index() on page 1374

max_index() on page 1377

min_index() on page 1382

25.3.7

fast_delete()

Purpose
Delete an item without adjusting all indexes

Category
Pseudo-method

Syntax
list.fast_delete(index: int)
Syntax Example
var l_list: list of int = {2; 4; 6; 8};
l_list.fast_delete(1);

Parameters
list

A list.

index

The index that is to be deleted from the list.

Specman e Language Reference


1999-2015

1332

Product Version 15.1


All Rights Reserved.

Description
Removes item number index from list (indexes start counting from 0). The index of the last item in the
list is changed to the index of the item that was deleted, so all items following the deleted item keep their
original indexes except that the original last index is removed.
If the index does not exist in the list, an error is issued.
Note In a keyed list, if two or more list items have the same key, the results of using list
pseudo-methods are unpredictable. See Keyed List Pseudo-Methods on page 1423.

Example
The following deletes C from index position 2 in the list named y_list, and changes the index of the
last item from 4 to 2. The new y_list is A, B, E, D.
<'
extend sys {
run() is also {
var y_list := {"A"; "B"; "C"; "D"; "E"};
y_list.fast_delete(2);
print y_list;
};
};
'>

See Also

Tip: Do Not Use delete(0) to Remove Items from the Beginning of a List in Specman Performance

Handbook

clear() on page 1329

delete() on page 1330

pop() on page 1337

pop0() on page 1338

resize() on page 1342

first_index() on page 1363

get_indices() on page 1366

last_index() on page 1374

max_index() on page 1377

min_index() on page 1382

Specman e Language Reference


1999-2015

1333
.

Product Version 15.1


All Rights Reserved.

25.3.8

insert(index, item)

Purpose
Insert an item in a list at a specified index

Category
Pseudo-method

Syntax
list.insert(index: int, item: list-type)
Syntax Example
var l_list := {10; 20; 30; 40; 50};
l_list.insert(3, 99);

Parameters
list

A list.

index

The index in the list where the item is to be inserted.

item

An item of the same type as the list.

Description
Inserts the item at the index location in the list. If index is the size of the list, then the item is simply
added at the end of the list. All indexes in the list are adjusted to keep the numbering correct.
If the number of items in the list is smaller than index, an error is issued.
Notes

For multi-dimensional lists, the item:

Must be a sublist with one dimension less than the main list

The basic type of the sublist must be the same as the basic type of the main list.

In other words, in the expression md-list1.insert(3, md-list2), md-list2 must have one dimension
less than md-list1 and its basic type must be the same as the basic type for md-list1.

Specman e Language Reference


1999-2015

1334

Product Version 15.1


All Rights Reserved.

If the item is a struct or a list, a pointer to the list or struct instance is simply added to the list. (For
information about creating new structs, use the new, gen, copy(), deep_copy(), and unpack() links
in the See Also list below.)

Example
In the following example, 10 is first inserted into position 2 in s_list, and then 77 is inserted into
position 1. The resulting list contains 5, 77, 1, 10.
var s_list := {5; 1};
s_list.insert(2,10);
s_list.insert(1,77);

See Also

new on page 125

gen...keeping on page 653

The copy() Method of any_struct or any_unit on page 1178

deep_copy() on page 1458

unpack() on page 1064

add(item) on page 1321

add(list) on page 1323

add0(item) on page 1325

add0(list) on page 1327

insert(index, list) on page 1335

push() on page 1339

push0() on page 1341

resize() on page 1342

25.3.9

insert(index, list)

Purpose
Insert a list in another list starting at a specified index

Category
Pseudo-method
Specman e Language Reference
1999-2015

1335
.

Product Version 15.1


All Rights Reserved.

Syntax
list_1.insert(index: int, list_2: list)
Syntax Example
var l_list := {10; 20; 30; 40; 50};
var m_list := {11; 12; 13};
l_list.insert(1, m_list);

Parameters
list_1

A list.

index

The index of the position in list_1 where list_2 is to be inserted.

list_2

A list that is to be inserted into list_1.

Description
Inserts all items of list_2 into list_1 starting at index. The index must be a positive integer. The size of
the new list size is equal to the sum of the sizes of list_1 and list_2.
If the number of items in list_1 is smaller than index, an error is issued.
The rules for using list_1.insert(index, list_2) with multi-dimensional lists are as follows:

The number of dimensions of list_2 must either equal the number of dimensions of list_1 or be one
less than the number of dimensions of list_1.
The basic element type of list_2 must be exactly the same as the basic element type for list_1.

This is illustrated in the following example:


var md_list1: list
var md_list2: list
var md_list3: list
var md_list4: list
var md_list5: list
var i: int;
md_list1.insert(0,
md_list1.insert(0,
md_list1.insert(0,
md_list3.insert(0,
md_list1.insert(0,

Specman e Language Reference


1999-2015

of
of
of
of
of

list
list
list
int;
list

of list of int;
of real;
of int;
of list of int;

md_list2);
i);
md_list3);
md_list4);
md_list5);

//
//
//
//
//

Fails--The list types are incompatible.


Fails--The added item is not a list.
Succeeds.
Succeeds.
Succeeds.

1336

Product Version 15.1


All Rights Reserved.

Example
In the following example, blue, green, and red are inserted after red in the colors_1 list. The
colors_l list is then red, blue, green, red, green, blue.
var colors_14 := {"red"; "green"; "blue"};
var colors_15 := {"blue"; "green"; "red"};
colors_14.insert(1, colors_15);

See Also

add(item) on page 1321

add(list) on page 1323

add0(item) on page 1325

add0(list) on page 1327

insert(index, item) on page 1334

push() on page 1339

push0() on page 1341

resize() on page 1342

25.3.10 pop()
Purpose
Remove and return the last list item

Category
Pseudo-method

Syntax
list.pop(): list-type
Syntax Example
var i_list:= {10; 20; 30};
var i_item: int;
i_item = i_list.pop();

Specman e Language Reference


1999-2015

1337
.

Product Version 15.1


All Rights Reserved.

Parameters
list

A list.

Description
Removes the last item (the item at index list.size() - 1) in the list and returns it. If the list is empty, an
error is issued.
Note

Use list.top0() to return the first item in list without removing it from the list.

Example
In the following example, the s_item variable gets d, and the s_list becomes a, b, c.
var s_item: string;
var s_list := {"a"; "b"; "c"; "d"};
s_item = s_list.pop();

See Also

pop0() on page 1338

delete() on page 1330

top() on page 1397

25.3.11 pop0()
Purpose
Remove and return the first list item

Category
Pseudo-method

Syntax
list.pop0(): list-type
Syntax Example
var i_list:= {10; 20; 30};
Specman e Language Reference
1999-2015

1338

Product Version 15.1


All Rights Reserved.

var i_item: int;


i_item = i_list.pop0();

Parameters
list

A list.

Description
Removes the first item (the item at index 0) from the list and returns it. Subtracts 1 from the index of
each item remaining in the list. If the list is empty, an error is issued.
Note

Use list.top0() to return the first item in list without removing it from the list.

Example
In the following example, the s_item variable gets a and s_list becomes b, c, d.
var s_item: string;
var s_list := {"a"; "b"; "c"; "d"};
s_item = s_list.pop0();

See Also

delete() on page 1330

pop() on page 1337

top0() on page 1398

25.3.12 push()
Purpose
Add an item to the end of a list (same as add(item) on page 1321)

Category
Pseudo-method

Syntax
list.push(item: list-type)
Specman e Language Reference
1999-2015

1339
.

Product Version 15.1


All Rights Reserved.

Syntax Example
var i_list: list of int;
i_list.push(5);

Parameters
list

A list.

item

An item of the same type as the list type, which is to be added to the list. The item is added
at index list.size(). That is, if the list contains five items, the last item is at index list.size() 1, or 4. Adding an item to this list places it at index 5.

Description
This pseudo-method performs the same function as add(item) on page 1321.
Notes

For multi-dimensional lists, the item:

Must be a sublist with one dimension less than the main list

The basic type of the sublist must be the same as the basic type of the main list.

In other words, in the expression md-list1.push(md-list2), md-list2 must have one dimension less
than md-list1 and its basic type must be the same as the basic type for md-list1.

If the item is a struct or a list, a pointer to the list or struct instance is simply added to the list. (For
information about creating new structs, use the new, gen, copy(), deep_copy(), and unpack() links
in the See Also list below.)

See Also

new on page 125

gen...keeping on page 653

The copy() Method of any_struct or any_unit on page 1178

deep_copy() on page 1458

unpack() on page 1064

add(item) on page 1321

add(list) on page 1323

add0(item) on page 1325

add0(list) on page 1327

Specman e Language Reference


1999-2015

1340

Product Version 15.1


All Rights Reserved.

insert(index, item) on page 1334

insert(index, list) on page 1335

push0() on page 1341

25.3.13 push0()
Purpose
Add an item to the head of a list (same as add0(item) on page 1325)

Category
Pseudo-method

Syntax
list.push0(item: list-type)
Syntax Example
var l_list: list of int = {4; 6; 8};
l_list.push0(2);

Parameters
list

A list.

item

An item of the same type as the list items, which is to be added to the head of the list.

Description
This pseudo-method performs the same function as add0(item) on page 1325.
Notes

For multi-dimensional lists, the item:

Must be a sublist with one dimension less than the main list

The basic type of the sublist must be the same as the basic type of the main list.

In other words, in the expression md-list1.push0(md-list2), md-list2 must have one dimension
less than md-list1 and its basic type must be the same as the basic type for md-list1.

Specman e Language Reference


1999-2015

1341
.

Product Version 15.1


All Rights Reserved.

If the item is a struct or a list, a pointer to the list or struct instance is simply added to the list. (For
information about creating new structs, use the new, gen, copy(), deep_copy(), and unpack() links
in the See Also list below.)

See Also

new on page 125

gen...keeping on page 653

The copy() Method of any_struct or any_unit on page 1178

deep_copy() on page 1458

unpack() on page 1064

add(item) on page 1321

add(list) on page 1323

add0(item) on page 1325

add0(list) on page 1327

insert(index, item) on page 1334

insert(index, list) on page 1335

push() on page 1339

25.3.14 resize()
Purpose
Change the size of a list

Category
Pseudo-method

Syntax
list.resize(size: int [, full: bool, filler: exp, keep_old: bool])
Syntax Example
var r_list := {2; 3; 5; 6; 8; 9};
r_list.resize(10, TRUE, 1, TRUE);

Specman e Language Reference


1999-2015

1342

Product Version 15.1


All Rights Reserved.

Parameters
list

A list.

size

A positive integer specifying the desired size.

full

A Boolean value specifying all items will be filled with filler. Default: TRUE.

filler

An item of the same type of the list items, used as a filler when FULL is TRUE.

keep_old

A Boolean value specifying whether to keep existing items already in the list. Default:
FALSE.

Description
Allocates a new list of declared size, or resizes an old list if keep_old is TRUE. If full is TRUE, sets all
new items to have filler as their value.
If only the first parameter, size, is used, this method allocates a new list of the given size and all items
are initialized to the default value for the list type.
If any of the three parameters after size are used, all three of them must be used.
To resize a list and keep its old values, set both full and keep_old to TRUE. If the list is made longer,
additional items with the value of filler are appended to the list.
Following is the behavior of this method for all combinations of full and keep_old.

full is FALSE, keep_old is FALSE:


An empty list (that is, a list of zero size) is created, and memory is allocated for a list of the given
size.

full is TRUE, keep_old is FALSE:


The list is resized to size, and filled completely with filler.

full is FALSE, keep_old is TRUE:

If size is greater than the size of the existing list, the list is enlarged to the new size, and the new
positions are filled with the default value of the list type.
If size is less than or equal to the size of the existing list, the list is shortened to the new size, and
all of the existing values up to that size are retained.

full is TRUE, keep_old is TRUE:

If size is greater than the size of the existing list, the list is enlarged to the new size, and the new
positions are filled with filler.

Specman e Language Reference


1999-2015

1343
.

Product Version 15.1


All Rights Reserved.

If size is less than or equal to the size of the existing list, the list is shortened to the new size, and
all of the existing values up to that size are retained.

Example 1
The following example puts 3 NULL instances of my_struct_s into y_list. The instances are NULL
because that is the default value for a struct instance. A list of byte is then unpacked into the list.
<'
struct my_struct_s {
%a: byte;
%b: byte;
%c: byte;
%d: byte;
};
extend sys {
run() is also {
var data: list of byte;
data = {1;2;3;4;5;6;7;8;9;10;11;12};
var y_list: list of my_struct_s;
y_list.resize(3);
print y_list.size();
for each in y_list {
print it;
};
unpack(packing.high, data, y_list);
for each in y_list {
print it;
};
};
};
'>

Result
y_list.size() = 3
it = (NULL)
it = (NULL)
it = (NULL)

Specman e Language Reference


1999-2015

1344

Product Version 15.1


All Rights Reserved.

it = my_struct_s-@0: my_struct_s
of unit: sys
---------------------------------------------0 %a:
12
1 %b:
11
2 %c:
10
3 %d:
9
it = my_struct_s-@1: my_struct_s
of unit: sys
---------------------------------------------0 %a:
8
1 %b:
7
2 %c:
6
3 %d:
5
it = my_struct_s-@2: my_struct_s
of unit: sys
---------------------------------------------0 %a:
4
1 %b:
3
2 %c:
2
3 %d:
1

@test

@test

@test

Example 2
The following example creates an empty list with memory allocated for a size of 3. The first print action
prints the size of the list, but the second print action has no output because there are no struct instances
in the list. A list of byte is then unpacked into the list, and the third print action prints the contents of
each struct instance in the list.
As is the previous example, the first field defined in the first struct allocated (my_struct_s-@0) gets the
value 12, the second field in that struct instance gets the value 11, and so on. However, the order in
which the struct instances appear in the list is reversed. In this example, my_struct_s-@2 is in y_list[0].
This is because Specman first allocates a sufficient number of struct instances to hold the bytes in data
and then assigns the instances to y_list.
<'
struct my_struct_s {
%a: byte;
%b: byte;
%c: byte;
%d: byte;
};
extend sys {
run() is also {
var data: list of byte;
data = {1;2;3;4;5;6;7;8;9;10;11;12};
var y_list: list of my_struct_s;
Specman e Language Reference
1999-2015

1345
.

Product Version 15.1


All Rights Reserved.

y_list.resize(3, FALSE, NULL, FALSE);


print y_list.size();
for each in y_list {
print it;
};
unpack(packing.high, data, y_list);
for each in y_list {
print it;
};
};
};
'>

Result
y_list.size() = 0
it = my_struct_s-@2: my_struct_s
of unit: sys
----------------------------------------------@test
0%a:
4
1%b:
3
2%c:
2
3%d:
1
it = my_struct_s-@1: my_struct_s
of unit: sys
----------------------------------------------@test
0%a:
8
1%b:
7
2%c:
6
3%d:
5
it = my_struct_s-@0: my_struct_s
of unit: sys
----------------------------------------------@test
0%a:
12
1%b:
11
2%c:
10
3%d:
9

Example 3
The following example puts 5 strings in r_list. The initial size of the list is 0 when it is created by the
var command.
Specman e Language Reference
1999-2015

1346

Product Version 15.1


All Rights Reserved.

var r_list: list of string;


r_list.resize(5, TRUE, "filler", FALSE);
print r_list.size();
print r_list;

Result
r_list.size() = 5
r_list =
0.
"filler"
1.
"filler"
2.
"filler"
3.
"filler"
4.
"filler"

Example 4
The following example makes s_list an empty list, but allocates space for it to hold 20 integers. The
initial size of the list is 0 when it is created by the var command, since full is FALSE.
var s_list: list of int;
s_list.resize(20, FALSE, 0, FALSE);
print s_list.size();
print s_list;

Result
s_list.size() = 0
s_list = (empty)

Example 5
The following example adds four items to an existing list.
var r_list := {2; 3; 5; 6; 8; 9};
r_list.resize(10, TRUE, 1, TRUE);
print r_list.size();
print r_list;

Result
r_list.size() = 10
r_list =
0.
2
1.
3
2.
5
Specman e Language Reference
1999-2015

1347
.

Product Version 15.1


All Rights Reserved.

3.
4.
5.
6.
7.
8.
9.

6
8
9
1
1
1
1

Example 6
This example shortens an existing list.
var r_list := {2; 3; 5; 6; 8; 9};
r_list.resize(4, TRUE, 7, TRUE);
print r_list.size();
print r_list;

Result
r_list.size() = 4
r_list =
0.
2
1.
3
2.
5
3.
6

See Also

add(item) on page 1321

add(list) on page 1323

add0(item) on page 1325

add0(list) on page 1327

insert(index, item) on page 1334

insert(index, list) on page 1335

push() on page 1339

push0() on page 1341

max_index() on page 1377

size() on page 1388

Specman e Language Reference


1999-2015

1348

Product Version 15.1


All Rights Reserved.

25.4 General List Pseudo-Methods


This section describes the syntax for pseudo-methods that perform various operations on lists.
The pseudo-methods in this section are:

all_different() on page 1350

all_different() (Conditional) on page 1351

apply() on page 1353

copy() on page 1356

count() on page 1357

exists() on page 1359

field (for List Item) on page 1360

first() on page 1361

first_index() on page 1363

flatten() on page 1364

get_indices() on page 1366

has() on page 1367

is_a_permutation() on page 1369

is_empty() on page 1371

last() on page 1372

last_index() on page 1374

max() on page 1376

max_index() on page 1377

max_value() on page 1379

min() on page 1381

min_index() on page 1382

min_value() on page 1384

reverse() on page 1386

size() on page 1388

sort() on page 1390

sort_by_field() on page 1392

split() on page 1393

top() on page 1397

top0() on page 1398

Specman e Language Reference


1999-2015

1349
.

Product Version 15.1


All Rights Reserved.

unique() on page 1399

See Also

Pseudo-Methods Overview on page 1319

Using List Pseudo-Methods on page 1320

25.4.1

all_different()

Purpose
Returns TRUE if evaluation of the expression returns a unique value for each of the list elements.

Category
Pseudo-method

Syntax
list.all_different(item: exp): bool
Syntax Example
keep my_list.all_different(it);

Parameters
list

A list.

item Any expression. The it variable can be used to refer to the current list item, and the index
variable can be used to refer to its index number.

Description
Returns TRUE if, and only if, evaluation of the expression returns a unique value for each of the list
elements, meaning no two items (or expressions) in the list have the same value.
Note Unlike most list pseudo-methods, all_different()is a generative (bidirectional) list
pseudo-method. For more information, see Using Bidirectional Generative List Pseudo-Methods in the
Specman Generation User Guide.

Specman e Language Reference


1999-2015

1350

Product Version 15.1


All Rights Reserved.

Example 1
<'
extend sys {
L:list of uint;
keep L.all_different(it);
};
'>

Example 2

Using all_different() on a List of Structs

<'
struct packet {
x: byte;
y: byte;
};
extend sys {
packets: list of packet;
keep packets.all_different(.x+.y);
};
'>

Example 3

Contradiction When Using all_different()

<'
extend sys {
L[11]: list of uint [1..10];
keep L.all_different(it);
};
'>

See Also

Using Bidirectional Generative List Pseudo-Methods in Specman Generation User Guide

all_different() (Conditional) on page 1351

25.4.2

all_different() (Conditional)

Purpose
Returns TRUE if, and only if, each list element for which a given Boolean expression returns TRUE also
evaluates to a unique value.

Specman e Language Reference


1999-2015

1351
.

Product Version 15.1


All Rights Reserved.

Category
Pseudo-method

Syntax
list.all_different(item: exp, bool_exp: bool): bool
Syntax Example
print l.all_different(it, it!=0);

Parameters
list

A list.

item

Any expression. The it variable can be used to refer to the current list item, and the index
variable can be used to refer to its index number.

bool_exp Any Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns TRUE if, and only if, for each two items in the list, when the bool_exp for both items evaluates
to TRUE then the items themselves evaluate to different values. In other words, no two items (or
expressions) in the list for which the bool_exp is TRUE have the same value.
Use this version of all_different() to create constraints that apply all_different() to a subset of the list
items.
Note Unlike most list pseudo-methods, all_different() is a generative (bidirectional) list
pseudo-method. For more information, see Using Bidirectional Generative List Pseudo-Methods in the
Specman Generation User Guide.

Example 1
var l: list of int = {UNDEF,3,2,1,UNDEF,4,UNDEF,6};
print l.all_different(it , it != UNDEF);
// Prints TRUE because all the elements different from UNDEF
// are also different from each other.
print l.all_different(it , index%2==1);
// Prints TRUE because all the elements on the
// odd indices are different from each other.
print l.all_different(it + index , index%2==1);
// Prints FALSE because the expression at index 1 (3+1)
Specman e Language Reference
1999-2015

1352

Product Version 15.1


All Rights Reserved.

// is not different from the expression at index 3 (1+3).

Example 2
The following example generates a list of packets such that all the sent packets will be sent using a
different socket ID.
struct packet {
sent : bool;
socket_id : int;
keep !sent => (socket_id == UNDEF);
};
ps : list of packet;
keep ps.all_different(it.socket_id, it.sent);

See Also

Applying List Pseudo-Methods Conditionally in Constraints in Specman Generation User Guide

all_different() on page 1350

25.4.3

apply()

Purpose
Perform a computation on each item in a list

Category
Pseudo-method

Syntax
list.apply(item: exp): list
Syntax Example
var p_list:= {1; 3; 5};
var n_list: list of int;;
n_list = p_list.apply(it*2);

Specman e Language Reference


1999-2015

1353
.

Product Version 15.1


All Rights Reserved.

Parameters
list

A list.

item Any expression. The it variable can be used to refer to the current list item, and the index
variable can be used to refer to its index number.

Description
Applies the exp to each item in the list and returns the changed list.

Note
The expression list.apply(it.field) is the same as list.field when field is a scalar type. For example,
the following expressions both return a concatenated list of the addr field in each packet item:
packets.apply(it.addr)
sys.packets.addr

The two expressions are different, however, if the field not scalar. For example, assuming that data is
a list of byte, the first expression returns a list containing the first byte of data of each packet item. The
second expression is a single item, which is the first item in the concatenated list of all data fields in
all packet items.
packets.apply(it.data[0])
packets.data[0]

Example 1
In the following example, the n_list in the sys struct gets a list of integers resulting from adding 1 to
each len value in the list of packets.
<'
struct packet {
len: uint;
addr: byte;
data: list of bit;
!%crc: uint;
};
extend sys {
p_list: list of packet;
!n_list: list of uint;
run() is also {
n_list = p_list.apply(it.len + 1);
};
};
Specman e Language Reference
1999-2015

1354

Product Version 15.1


All Rights Reserved.

'>

Example 2
In the following example, the packet struct contains a get_crc() method that calls the predefined
crc_32() on page 1419. The crc_plus list gets the values returned by applying the get_crc() method
to every packet in the p_list list.
<'
struct packet {
%len: uint;
%addr: byte;
%data: list of byte;
!%crc: int;
get_crc(): int is {
return data.crc_32(0, data.size());
};
};
extend sys {
p_list: list of packet;
!crc_plus: list of int;
post_generate() is also {
crc_plus = p_list.apply(it.get_crc());
};
};
'>

Example 3
In the following example, the ind_list gets the indexes (0, 1, 2) of the items in the l_list.
var l_list: list of int = {5; 7; 9};
var ind_list: list of int = l_list.apply(index);
print ind_list;

See Also

field (for List Item) on page 1360

all() on page 1401

Specman e Language Reference


1999-2015

1355
.

Product Version 15.1


All Rights Reserved.

25.4.4

copy()

Purpose
Make a shallow copy of a list

Category
Predefined method of any struct or unit

Syntax
list.copy(): list
Syntax Example
var strlist_1: list of string = {"A"; "B"; "C"};
var strlist_2: list of string;
strlist_2 = strlist_1.copy();

Description
This is a specific case of exp.copy(), where exp is the name of a list.
The following list details how the copy is made, depending on the type of the expression:
scalar list

If exp is a scalar list, a new list with the same size as the original list is allocated.
The contents of the original list is duplicated.

list of structs

A new list with the same size as the original list is allocated. The contents of the list
is copied by reference, meaning that each item in the new list points to the
corresponding item in the original list.

Notes

Do not use the assignment operator (=) to copy lists into other data objects. The assignment operator
simply manipulates pointers to the data being assigned and does not create new struct instances or lists.
Use the deep_copy() method if you want a recursive copy of a list that contains compound fields or
items.

See Also

The copy() Method of any_struct or any_unit on page 1178

Specman e Language Reference


1999-2015

1356

Product Version 15.1


All Rights Reserved.

25.4.5

count()

Purpose
Return the number of items that satisfy a given condition

Category
Pseudo-method

Syntax
list.count(exp: bool): int
Syntax Example
var ct: int;
ct = instr_list.count(it.op1 > 200);

Parameters
list

A list.

exp

A Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the number of items for which the exp is TRUE.

Notes

Unlike most list pseudo-methods, count() is a generative (bidirectional) list pseudo-method. For
more information, see Using Bidirectional Generative List Pseudo-Methods in the Specman
Generation User Guide.
Note that the syntax list.all(exp).size() returns the same result as the list.count(exp) pseudo-method,
but list.all(exp).size() creates a new list while list.count(exp) does not.

Example 1
The following example prints 3, since there are three items in l_list with values greater than 3.
var l_list: list of int = {2; 3; 4; 5; 6};
Specman e Language Reference
1999-2015

1357
.

Product Version 15.1


All Rights Reserved.

print l_list.count(it > 3);

Example 2
The following example prints the number of packet struct instances in the packets list that have a
length field value smaller than 5.
<'
struct packet {
length: uint (bits: 4);
};
extend sys {
packets: list of packet;
post_generate() is also {
var pl: int;
pl = packets.count(.length < 5);
print pl;
};
};
'>

Example 3
The following example illustrates the use of count() to set a ratio between different types of list items.
<'
type length_t: [SHORT, MEDIUM, LONG];
struct packet{
length: length_t;
};
extend sys{
l: list of packet;
-- twice as many long packets than short packets.
keep l.count(it.length == SHORT) ==
2*l.count(it.length == LONG);
-- medium packets are at least 2/3 of all packets in the list.
keep l.count(it.length == MEDIUM) >
2*( l.count(it.length == SHORT) +
l.count(it.length == LONG) );
keep l.size() > 18;
};
'>

Specman e Language Reference


1999-2015

1358

Product Version 15.1


All Rights Reserved.

See Also

has() on page 1367

all() on page 1401

all_indices() on page 1403

key() on page 1423

key_exists() on page 1428

25.4.6

exists()

Purpose
Check if an index exists in a list

Category
Pseudo-method

Syntax
list.exists(index: int): bool
Syntax Example
var i_chk: bool;
i_chk = packets.exists(5);

Parameters
list

A list.

index

An integer expression representing an index to the list.

Description
Returns TRUE if an item with the index number exists in the list, or returns FALSE if the index does not
exist.

Specman e Language Reference


1999-2015

1359
.

Product Version 15.1


All Rights Reserved.

Example
The first print action in the following prints TRUE, because the int_list contains an item with an
index of 1. The second print action prints FALSE, because there is no item with index 7 in the list.
<'
extend sys {
run() is also {
var int_lst: list of int = {1; 2; 3; 4; 5};
var ind_ex: bool;
ind_ex = int_lst.exists(1);
print ind_ex;
ind_ex = int_lst.exists(7);
print ind_ex;
};
};
'>

See Also

first_index() on page 1363

all_indices() on page 1403

25.4.7

field (for List Item)

Purpose
Specifying a field from all items in a list

Category
Pseudo-method

Syntax
list.field-name
Syntax Example
s_list.fld_nm

Specman e Language Reference


1999-2015

1360

Product Version 15.1


All Rights Reserved.

Parameters
list

A list of structs.

field-name

A name of a field or list in the struct type.

Description
Returns a list containing the contents of the specified field-name for each item in the list. If the list is
empty, it returns an empty list. This syntax is the same as list.apply(field).
An error is issued if the field name is not the name of a struct or if the struct type does not have the
specified field

Example
The following prints the values of the length fields in all the items in the packets list.
<'
struct packet {
length: uint;
};
extend sys {
packets: list of packet;
run() is also {
print packets.length;
};
};
'>

See Also

apply() on page 1353

25.4.8

first()

Purpose
Get the first item that satisfies a given condition

Category
Pseudo-method
Specman e Language Reference
1999-2015

1361
.

Product Version 15.1


All Rights Reserved.

Syntax
list.first(exp: bool): list-type
Syntax Example
var i_item: instr;
i_item = instr_list.first(it.op1 > 15);

Parameters
list

A list.

exp

A Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the first item for which exp is TRUE. If there is no such item, the default for the items type is
returned (see e Data Types on page 137).
For a list of scalars, a value of zero is returned if there is no such item. Since zero might be confused
with a value found, it is safer to use list.first_index() for lists of scalars.

Example 1
The first command below creates a list of five integers. The second command prints the first item in the
list smaller than 5 (that is, it prints 3).
var i_list: list of int = {8;3;7;3;4};
print i_list.first(it < 5 );

Example 2
In the following example, the list.first() pseudo-method is used to make sure all items in the packets
list contain non-empty cells lists.
<'
struct cell {
data[8]: list of byte;
};
struct packet {
cells[10]: list of cell;
};
extend sys {
packets: list of packet;

Specman e Language Reference


1999-2015

1362

Product Version 15.1


All Rights Reserved.

run() is also {
assert sys.packets.first(.cells is empty) == NULL;
};
};
'>

See Also

first_index() on page 1363

has() on page 1367

last() on page 1372

25.4.9

first_index()

Purpose
Get the index of the first item that satisfies a given condition

Category
Pseudo-method

Syntax
list.first_index(exp: bool): int
Syntax Example
var i_item: int;
i_item = instr_list.first_index(it.op1 > 15);

Parameters
list

A list.

exp

A Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the index of the first item for which exp is TRUE or return UNDEF if there is no such item.

Specman e Language Reference


1999-2015

1363
.

Product Version 15.1


All Rights Reserved.

Example 1
The first command below creates a list of five integers. The second command prints 1, which is the
index of the first item in the list smaller than 5.
var i_list: list of int = {8;3;7;3};
print i_list.first_index(it < 5);

Example 2
In the following example, the list.first_index() pseudo-method is used to make sure all items in the
packets list contain non-empty cells lists.
<'
struct cell {
data[8]: list of byte;
};
struct packet {
cells[10]: list of cell;
};
extend sys {p
packets: list of packet;
run() is also {
assert packets.first_index(.cells is empty) == UNDEF;
};
};
'>

See Also

first() on page 1361

has() on page 1367

last_index() on page 1374

25.4.10 flatten()
Purpose
Get a list of the base elements that make up the sub-lists in a multi-dimensional list.

Category
Pseudo-method
Specman e Language Reference
1999-2015

1364

Product Version 15.1


All Rights Reserved.

Syntax
list.flatten(): list
Syntax Example
var matrix: list of list of int = {{1;2;3};{4;5;6}};
var l: list of int = matrix.flatten();

Parameters
list

A list.

Description
Returns a regular (one-dimensional) list that contains all the base elements that are contained in the list.
You can use it, for example, to identify whether a multi-dimensional list contains a given element, for
example:
md_list.flatten().has(it==4);

This pseudo-method is intended for use with multi-dimensional lists (lists of lists). If you use it with a
one-dimensional list, it simply returns a copy of the list.
Note If the multidimensional list is a keyed list, flatten() still returns a regular list, not a keyed list.
For example:
var matrix: list of list(key:it) of int;
var l: list of int = matrix.flatten();

Example
struct A {
x: int;
};
extend sys {
run() is also {
var matrix: list of list of int = {{1;2;3};{4;5;6}};
print matrix.flatten();
var
var
var
var

a1: A = new with


a2: A = new with
a3: A = new with
keyed_l: list of

Specman e Language Reference


1999-2015

{it.x = 1;};
{it.x = 2;};
{it.x = 3;};
list (key:x) of A = {{a1;a2};{a3}};
1365
.

Product Version 15.1


All Rights Reserved.

print keyed_l.flatten()
};
};

Results
0.
1.
2.
3.
4.
5.

matrix.flatten() =
1
2
3
4
5
6

keyed_l.flatten() =
item
type
x
----------------------------0.
A
1
1.
A
2
2.
A
3

See Also

first() on page 1361

has() on page 1367

last_index() on page 1374

25.4.11 get_indices()
Purpose
Return a sublist of another list

Category
Pseudo-method

Syntax
list.get_indices(index-list: list of int): list-type

Specman e Language Reference


1999-2015

1366

Product Version 15.1


All Rights Reserved.

Syntax Example
var i_list: list of packet;
i_list = packets.get_indices({0; 1; 2});

Parameters
list

A list.

index-list

A list of indexes within the list. Each index must exist in the list.

Description
Copies the items in list that have the indexes specified in index-list and returns a new list containing
those items. If the index-list is empty, an empty list is returned.

Example
The following example puts green and orange in the list named o_list.
var c_list := {"red"; "green"; "blue"; "orange"};
var o_list := c_list.get_indices({1;3});

See Also

first_index() on page 1363

has() on page 1367

last_index() on page 1374

all_indices() on page 1403

25.4.12 has()
Purpose
Check that a list has at least one item that satisfies a given condition

Category
Pseudo-method

Specman e Language Reference


1999-2015

1367
.

Product Version 15.1


All Rights Reserved.

Syntax
list.has(exp: bool): bool
Syntax Example
var i_ck: bool;
i_ck = sys.instr_list.has(it.op1 > 31);

Parameters
list

A list.

exp

A Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns TRUE if the list contains at least one item for which the exp is TRUE, or returns FALSE if the
expression is not TRUE for any item.
Note Unlike most list pseudo-methods, has() is a generative (bidirectional) list pseudo-method. For
more information, see Using Bidirectional Generative List Pseudo-Methods in the Specman Generation
User Guide.

Example 1
The first command below creates a list containing the integers 8, 3, 7, and 3. The second command
checks that the list contains 7, and prints TRUE.
var l: list of int = {8;3;7;3};
print l.has(it == 7);

Example 2
The command below checks that there is no packet in the packets list that contains an empty cells
list.
<'
struct cell {
data[8]: list of byte;
};
struct packet {
cells[10]: list of cell;
};
extend sys {
Specman e Language Reference
1999-2015

1368

Product Version 15.1


All Rights Reserved.

packets: list of packet;


run() is also {
assert not sys.packets.has(.cells is empty);
};
};
'>

See Also

first() on page 1361

last() on page 1372

max() on page 1376

min() on page 1381

all() on page 1401

25.4.13 is_a_permutation()
Purpose
Check that two lists contain exactly the same items

Category
Pseudo-method

Syntax
list_1.is_a_permutation(list_2: list): bool
Syntax Example
var lc: bool;
lc = packets_1a.is_a_permutation(packets_1b);

Parameters
list_1

A list.

list_2

A list that is to be compared to list_1. Must be the same type as list_1.

Specman e Language Reference


1999-2015

1369
.

Product Version 15.1


All Rights Reserved.

Description
Returns TRUE if list_2 contains the same items as list_1, or FALSE if any items in one list are not in the
other list. The order of the items in the two lists does not need to be the same, but the number of items
must be the same for both lists. That is, items that are repeated in one list must appear the same number
of times in the other list for one list to be a permutation of the other list.

Notes

If the lists are lists of structs, list_1.is_a_permutation(list_2) compares the addresses of the struct
items, not their contents.
This pseudo-method can be used in a keep constraint to fill list_1 with the same items contained in
the list_2, although not necessarily in the same order.

Example 1
In the following example, the l_comp variable is TRUE because the two lists contain the same items.
<'
extend sys {
run() is also {
var l_1 := {1;3;5;7;9};
var l_2 := {1;9;7;3;5};
var l_comp: bool;
l_comp = l_1.is_a_permutation(l_2);
print l_comp;
};
};
'>

Example 2
In the following example, the keep constraint causes the list named l_2 have the same items the
Specman generator puts in the list named l_1. Since l_1 will have the same number of items as
l_2, there is an implicit constraint that l_2 will be the same size at l_1. To constrain the size of the
two lists, you can specify a keep constraint on the size of either l_1 or l_2. Using a keep soft
constraint to try to constrain the size of l_2 is an error.
<'
extend sys {
l_1: list of int;
l_2: list of int;
keep l_2.is_a_permutation(l_1);
};
'>

Specman e Language Reference


1999-2015

1370

Product Version 15.1


All Rights Reserved.

See Also

keep on page 620

has() on page 1367

25.4.14 is_empty()
Purpose
Check if a list is empty

Category
Pseudo-method

Syntax
list.is_empty(): bool
Syntax Example
var no_l: bool;
no_l = packets.is_empty();

Parameters
list

A list.

Description
Returns TRUE if list is empty, or FALSE if the list is not empty.

Note
You can use list is empty as a synonym for list.is_empty().
Similarly, you can use list is not empty to mean not(list.is_empty()).

Example 1
In the following example, the first print action prints TRUE because the int_lst is initially empty.
After an item is added, the second print action prints TRUE because the list is not empty.
Specman e Language Reference
1999-2015

1371
.

Product Version 15.1


All Rights Reserved.

<'
extend sys {
!int_list: list of int;
run() is also {
var emp: bool;
emp = int_list.is_empty();
print emp;
int_list.add(3);
emp = int_list is not empty;
print emp;
};
};
'>

Example 2
The following prints a formatted string if a list is empty.
ck_instr() is {
if int_list is not empty {
print int_list;
}
else {
outf("list is empty\n");
};
};

See Also

clear() on page 1329

exists() on page 1359

size() on page 1388

25.4.15 last()
Purpose
Get the last item that satisfies a given condition

Category
Pseudo-method

Specman e Language Reference


1999-2015

1372

Product Version 15.1


All Rights Reserved.

Syntax
list.last(exp: bool): list-type
Syntax Example
var i_item: instr;
i_item = sys.instr_list.last(it.op1 > 15);

Parameters
list

A list.

exp

A Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the last item in the list that satisfies the Boolean expression. If there is no such item, the default
for the items type is returned (see e Data Types on page 137).
For a list of scalars, a value of zero is returned if there is no such item. Since zero might be confused
with a found value, it is safer to use list.last_index() for lists of scalars.

Example 1
The first command below creates a list containing the integers 8, 3, 7, 3, and 4. The second command
prints 4.
var l :list of int = {8;3;7;3;4};
print l.last(it < 5);

Example 2
The command below checks that there is no packet in the packets list that contains an empty cells
list.
<'
struct cell {
data[8]: list of byte;
};
struct packet {
cells[10]: list of cell;
};
extend sys {
packets: list of packet;

Specman e Language Reference


1999-2015

1373
.

Product Version 15.1


All Rights Reserved.

run() is also {
assert sys.packets.last(.cells is empty) == NULL;
};
};
'>

See Also

first() on page 1361

has() on page 1367

last_index() on page 1374

all() on page 1401

25.4.16 last_index()
Purpose
Get the index of the last item that satisfies a given condition

Category
Pseudo-method

Syntax
list.last_index(exp: bool): int
Syntax Example
var i_item: int;
i_item = instr_list.last_index(it.op1 > 15);

Parameters
list

A list.

exp

A Boolean expression. The it variable can be used to refer to the current list
item, and the index variable can be used to refer to its index number.

Specman e Language Reference


1999-2015

1374

Product Version 15.1


All Rights Reserved.

Description
Returns the index of the last item for which exp is TRUE, or returns UNDEF if there is no such item.

Example 1
The first command below creates a list containing the integers 8, 3, 7, 3, and 4. The second command
prints 3.
var l: list of int = {8;3;7;3;4};
print l.last_index(it == 3);

Example 2
The following example checks that every packet in the packets list has a non-empty cells list. If the
index of the last packet that has a non-empty cells list is one less than the size of the list, the check
succeeds.
<'
struct cell {
data[8]: list of byte;
};
struct packet {
cells[10]: list of cell;
};
extend sys {p
packets: list of packet;
run() is also {
assert packets.last_index(.cells is empty) == UNDEF;
};
};
'>

See Also

first_index() on page 1363

has() on page 1367

last() on page 1372

all_indices() on page 1403

Specman e Language Reference


1999-2015

1375
.

Product Version 15.1


All Rights Reserved.

25.4.17 max()
Purpose
Get the item with the maximum value of a given expression

Category
Pseudo-method

Syntax
list.max(exp: int): list-type
Syntax Example
var high_item: item_instance;
high_item = item_list.max(it.f_1 + it.f_2);

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the item for which the exp evaluates to the largest value. If more than one item results in the
same maximum value, the item latest in the list is returned.
If the list is empty, an error is issued.

Example
In the example below, the high_item variable gets the instr instance that has the largest value of the
sum of op1 and op2.
<'
struct instr {
op1: int;
op2: int;
};

Specman e Language Reference


1999-2015

1376

Product Version 15.1


All Rights Reserved.

extend sys {
instr_list: list of instr;
keep instr_list.size() > 5;
run() is also {
var high_item: instr;
high_item = instr_list.max(.op1 + .op2);
print high_item;
};
};
'>

See Also

has() on page 1367

max_index() on page 1377

max_value() on page 1379

min() on page 1381

all() on page 1401

25.4.18 max_index()
Purpose
Get the index of the item with the maximum value of a given expression

Category
Pseudo-method

Syntax
list.max_index(exp: int): int
Syntax Example
var item_index: int;
item_index = sys.item_list.max_index(it.f_1 + it.f_2);

Parameters
list

A list.

Specman e Language Reference


1999-2015

1377
.

Product Version 15.1


All Rights Reserved.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the index of the item for which the exp evaluates to the largest value. If more than one item
results in the same maximum value, the index of the item latest in the list is returned.
If the list is empty, and error is issued.

Example
In the example below, the high_indx variable gets the index of the instr instance that has the largest
value of the sum of op1 and op2.
<'
struct instr {
op1: int;
op2: int;
};
extend sys {
instr_list: list of instr;
keep instr_list.size() > 5;
run() is also {
var high_indx: int;
high_indx = instr_list.max_index(.op1 + .op2);
print high_indx;
};
};
'>

See Also

first_index() on page 1363

has() on page 1367

last_index() on page 1374

max() on page 1376

max_value() on page 1379

min_index() on page 1382

all_indices() on page 1403

Specman e Language Reference


1999-2015

1378

Product Version 15.1


All Rights Reserved.

25.4.19 max_value()
Purpose
Return the maximum value found by evaluating a given expression for all items

Category
Pseudo-method

Syntax
list.max_value(exp: int): (int | uint)
Syntax Example
var item_val: int;
item_val = sys.item_list.max_value(it.f_1 + it.f_2);

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the largest integer value found by evaluating the exp for every item in the list. If more than one
item results in the same maximum value, the value of the expression for the item latest in the list is
returned.
Note Unlike most list pseudo-methods, max_value() is a generative (bidirectional) list
pseudo-method. For more information, see Using Bidirectional Generative List Pseudo-Methods in the
Specman Generation User Guide and the description of the -bidir_list_pseudo_methods flag in
configure gen in the Specman Command Reference.

When the List Is Empty


When max_value() is being used as a bidirectional pseudo-method, an empty list causes a contradiction.
When max_value() is being used as a unidirectional pseudo-methodfor example, if it is enclosed with
read_only()one of the following is returned if the list is empty:
Specman e Language Reference
1999-2015

1379
.

Product Version 15.1


All Rights Reserved.

List Item Type

Value Returned by Unidirectional max_value()

signed integer

MIN_INT (see Predefined Constants on page 39)

unsigned integer

zero

long integer

error

Example 1
The example below prints the largest absolute value in the list of integers named i_list.
<'
extend sys {
i_list: list of int;
run() is also {
print i_list.max_value(abs(it));
};
};
'>

Example 2
In the example below, the high_val variable gets the instr instance that has the largest value of the
sum of op1 and op2.
<'
struct instr {
op1: int;
op2: int;
};
extend sys {
instr_list: list of instr;
keep instr_list.size() < 10;
run() is also {
var high_val: int;
high_val = instr_list.max_value(.op1 + .op2);
print high_val;
};
};
'>

Example 3
The following code snippet generates a list of ints in which the maximum value in the list is greater than
the minimum value in the list by more than 20.
Specman e Language Reference
1999-2015

1380

Product Version 15.1


All Rights Reserved.

l : list of int;
keep l.size() >= 2;
keep l.max_value(it) >l.min_value(it) + 20;

See Also

has() on page 1367

max() on page 1376

max_index() on page 1377

min_value() on page 1384

25.4.20 min()
Purpose
Get the item with the minimum value of a given expression

Category
Pseudo-method

Syntax
list.min(exp: int): list-type
Syntax Example
var low_item: item_instance;
low_item = sys.item_list.min(it.f_1 + it.f_2);

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the item for which the exp evaluates to the smallest value. If more than one item results in the
same minimum value, the item latest in the list is returned.
Specman e Language Reference
1999-2015

1381
.

Product Version 15.1


All Rights Reserved.

Example
In the example below, the low_item variable gets the instr instance that has the smallest value of the
sum of op1 and op2.
<'
struct instr {
op1: int;
op2: int;
};
extend sys {
instr_list: list of instr;
keep instr_list.size() < 10;
run() is also {
var low_item: instr;
low_item = instr_list.min(.op1 + .op2);
print low_item;
};
};
'>

See Also

first() on page 1361

has() on page 1367

last() on page 1372

max() on page 1376

min_index() on page 1382

min_value() on page 1384

all() on page 1401

25.4.21 min_index()
Purpose
Get the index of the item with the minimum value of a given expression

Category
Pseudo-method

Specman e Language Reference


1999-2015

1382

Product Version 15.1


All Rights Reserved.

Syntax
list.min_index(exp: int): int
Syntax Example
var item_index: int;
item_index = sys.item_list.min_index(it.f_1 + it.f_2);

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Return the index of the item for which the specified exp gives the minimal value. If more than one item
results in the same minimum value, the index of the item latest in the list is returned.
If the list is empty, an error is issued.

Example
In the example below, the low_indx variable gets the index of the instr instance that has the smallest
value of the sum of op1 and op2.
<'
struct instr {
op1: int;
op2: int;
};
extend sys {
instr_list: list of instr;
keep instr_list.size() < 10;
run() is also {
var low_indx: int;
low_indx = instr_list.min_index(.op1 + .op2);
print low_indx;
};
};
'>

Specman e Language Reference


1999-2015

1383
.

Product Version 15.1


All Rights Reserved.

See Also

first_index() on page 1363

has() on page 1367

last_index() on page 1374

max_index() on page 1377

min() on page 1381

min_value() on page 1384

all_indices() on page 1403

25.4.22 min_value()
Purpose
Return the minimum value found by evaluating a given expression for all items

Category
Pseudo-method

Syntax
list.min_value(exp: int): (int | uint)
Syntax Example
var item_val: int;
item_val = sys.item_list.min_value(it.f_1 + it.f_2);

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Specman e Language Reference


1999-2015

1384

Product Version 15.1


All Rights Reserved.

Description
Returns the smallest integer value found by evaluating the exp for every item in the list. If more than one
item results in the same minimum value, the value of the expression for the item latest in the list is
returned.
Note Unlike most list pseudo-methods, min_value() is a generative (bidirectional) list
pseudo-method. For more information, see Using Bidirectional Generative List Pseudo-Methods in the
Specman Generation User Guide and the description of the -bidir_list_pseudo_methods flag in
configure gen in the Specman Command Reference.

When the List Is Empty


When min_value() is being used as a bidirectional pseudo-method, an empty list causes a contradiction.
When min_value() is being used as a unidirectional pseudo-methodfor example, if it is enclosed with
read_only()for lists of integer types, one of the following is returned if the list is empty:
List Item Type

Value Returned by Unidirectional min_value()

signed integer

MAX_INT (see Predefined Constants on page 39)

unsigned integer

zero

long integer

error

Example 1
In the example below, the low_val variable gets the instr instance that has the smallest value of the
sum of op1 and op2.
<'
struct instr {
op1: int;
op2: int;
};
extend sys {
instr_list: list of instr;
keep instr_list.size() < 10;
run() is also {
var low_val: int;
low_val = instr_list.min_value(.op1 + .op2);
print low_val;
};
};
'>
Specman e Language Reference
1999-2015

1385
.

Product Version 15.1


All Rights Reserved.

Example 2
The following code snippet generates a list of ints in which the maximum value in the list is greater than
the minimum value in the list by more than 20.
l : list of int;
keep l.size() >= 2;
keep l.max_value(it) >l.min_value(it) + 20;

See Also

has() on page 1367

max_value() on page 1379

min() on page 1381

min_index() on page 1382

25.4.23 reverse()
Purpose
Reverse the order of a list

Category
Pseudo-method

Syntax
list.reverse(): list
Syntax Example
var s_list := {"A"; "B"; "C"; "D"};
var r_list := s_list.reverse();

Parameters
list

A list.

Specman e Language Reference


1999-2015

1386

Product Version 15.1


All Rights Reserved.

Description
Returns a new list of all the items in list in reverse order.

Example 1
In the following example the r_list variable gets a list that contains all the items in the packets list,
but in reverse order.
<'
struct cell {
data: list of byte;
};
struct packet {
cells: list of cell;
};
extend sys {
packets: list of packet;
!r_packets: list of packet;
run() is also {
r_packets = packets.reverse();
};
};
'>

Example 2
The following example shows the use of reverse() with a multi-dimensional list:
extend sys {
run() is also {
var l: list of list of int = {{1;2;3};{4;5;6};{7;8;9}};
assert l.reverse() == {{7;8;9};{4;5;6};{1;2;3}};
};
};

Example 3
The following example prints 2, 1, 2, 4.
extend sys {
run() is also {
var i_list: list of int = {4; 2; 1; 2};
var r_list: list of int = i_list.reverse();
print r_list;
Specman e Language Reference
1999-2015

1387
.

Product Version 15.1


All Rights Reserved.

};
};

See Also

sort() on page 1390

sort_by_field() on page 1392

25.4.24 size()
Purpose
Return the size of a list

Category
Pseudo-method

Syntax
list.size(): int
Syntax Example
print packets.size();

Parameters
list

A list.

Description
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. The default maximum list size for generated lists is 50, set by the default_max_list_size
generation configuration option. Generated lists have a random size between 0 and that number. You can
control the list size using a construct like keep list.size() == n, where n is an integer expression.
The list[n] index syntax is another way to specify an exact size of a list, when you use it in the list
declaration, such as p_list[n]: list of p.

Specman e Language Reference


1999-2015

1388

Product Version 15.1


All Rights Reserved.

See Constraining List Size in the Specman Generation User Guide for more information about
constraining the size of lists.

Example 1
In the following example, the lsz variable gets the number of items in the list named s_list.
<'
extend sys {
s_list: list of string;
keep s_list == {"Aa"; "Ba"; "Cc"};
run() is also {
var lsz: int;
lsz = sys.s_list.size();
print lsz;
};
};
'>

Example 2
The following example shows the use of size() with a multi-dimensional list. The list matrix is defined
to contain four lists; the first of these sublists is defined with the size of three elements.
<'
struct packet {
matrix[4][3]: list of list of int;
};
extend sys {
p: packet;
run() is also {
assert p.matrix.size() == 4;
assert p.matrix[1].size() == 3;
};
};
'>

Example 3
In the following example, a list of packets named p_list will be generated. A keep constraint is used to
set the size of the list to exactly 10 packets.
<'
extend sys {
Specman e Language Reference
1999-2015

1389
.

Product Version 15.1


All Rights Reserved.

p_list: list of packet;


keep p_list.size() == 10;
};
'>

See Also

resize() on page 1342

count() on page 1357

keep on page 620

[ ] on page 103

25.4.25 sort()
Purpose
Sort a list

Category
Pseudo-method

Syntax
list.sort(sort-exp: exp): list
Syntax Example
var s_list: list of packet;
s_list = packets.sort(it.f_1 + it.f_2);

Parameters
list

A list of integers, strings, enumerated items, or Boolean values to sort.

sort-exp A scalar or nonscalar expression. The expression may contain references to fields or
structs. The it variable can be used to refer to the current list item.
Note

The sort expression cannot be a list, either one-dimensional or multi-dimensional

Specman e Language Reference


1999-2015

1390

Product Version 15.1


All Rights Reserved.

Description
Returns a new list of all the items in list, sorted in increasing order of the values of the sort-exp.
If the sort-exp is a scalar value, the list is sorted by value. If the sort-exp is a nonscalar, the list is sorted
by address.
Note Addresses are sensitive to allocation schemes and heap organization. Therefore, if you sort a list
of non-scalars before and after garbage collection, the order of items in the list might be different.

Example 1
The following example prints 1, 2, 2, 4.
var sl: list of int = {4; 2; 1; 2};
print sl.sort(it);

Example 2
In the following example, the s_list variable gets the items in the packets list, sorted in increasing
value of the product of the length and width fields.
<'
struct packet {
length: uint;
width: uint;
};
extend sys {
packets: list of packet;
run() is also {
var s_list: list of packet;
s_list = packets.sort(.length * .width);
};
};
'>

See Also

reverse() on page 1386

sort_by_field() on page 1392

Specman e Language Reference


1999-2015

1391
.

Product Version 15.1


All Rights Reserved.

25.4.26 sort_by_field()
Purpose
Sort a list of structs by a selected field

Category
Pseudo-method

Syntax
struct-list.sort_by_field(field: field-name): list
Syntax Example
var s_list: list of packet;
s_list = sys.packets.sort_by_field(length);

Parameters
struct-list

A list of structs.

field

The name of a field of the lists struct type. Enter the name of the field only, with no
preceding . or it..

Description
Returns a new list of all the items in struct-list, sorted in increasing order of their field values.

Note
The list.sort() pseudo-method returns the same value as the list.sort_by_field() pseudo-method, but
list.sort_by_field() is more efficient.

Example
In the following example, the sf_list variable gets the items in the packets list, sorted in increasing
value of the ptype field (first ATM, then ETH, then foreign).
<'
type pkt_type: [ATM, ETH, foreign];
Specman e Language Reference
1999-2015

1392

Product Version 15.1


All Rights Reserved.

struct packet {
length: uint;
width: uint;
ptype: pkt_type;
};
extend sys {
packets: list of packet;
run() is also {
var sf_list: list of packet;
sf_list = packets.sort_by_field(ptype);
print sf_list;
};
};
'>

See Also

reverse() on page 1386

sort() on page 1390

25.4.27 split()
Purpose
Splits a list at each point where an expression is true

Category
Pseudo-method

Syntax
input-list.split(split-exp: exp): struct_list_holder, ...
Syntax Example
var sl_hold := s_list.split(it.f_1 == 16);

Parameters
in

input-list

A list of type struct.

Specman e Language Reference


1999-2015

1393
.

Product Version 15.1


All Rights Reserved.

split-exp

An expression. The it variable can be used to refer to the current list item, and the index
variable can be used to refer to its index number.

Description
Splits the items in input-list into separate lists of type struct_list_holder. Each output list contains the
consecutive items in input-list that evaluate to the split-exp value.
This pseudo-method returns a list of type struct_list_holder. The struct_list_holder type is a struct with a
single field, value: list of any-struct; which is a list of items of the original input-list type.
Each struct_list_holder in the returned list contains consecutive items from the input-list that have the
same split-exp value.

Note
Fields used in the expression must be defined in the base type definition, not in when subtypes.

Example 1
Suppose packets is a list that contains packet instances that have the following length values:
3; 5; 5; 7; 7; 7; 5;
The packets.split(.length) pseudo-method in the following creates a list of four lists by splitting the
packets list at each point where the length value changes, that is, between 3 and 5, between 5 and 7,
and between 7 and 5.
<'
struct packet {
length: uint;
};
extend sys {
packets[7]: list of packet;
lengths: list of uint;
keep lengths == {3; 5; 5; 7; 7; 7; 5);
keep for each in packets {
.length == lengths[index];
};
run() is also {
var sl_hold := packets.split(.length);
for each in s1_hold {
print it.value;
};
};
};
Specman e Language Reference
1999-2015

1394

Product Version 15.1


All Rights Reserved.

'>

The struct_list_holder variable sl_hold then contains four lists:


3
5, 5
7, 7, 7
5
The print sl_hold[2].value action prints the third list, which is the one containing three items whose
length values are 7.
The print sl_hold.value[4] action prints the fifth item in the sl_hold list, which is the same as the
fifth item in the packets list.

Example 2
In the following example, the length field values used in Example 1 on page 1394, are assigned to a
list of seven packet structs. The list.split() pseudo-method is then called to split the list of packets on
the length values. This creates the following four lists in the sl_hold struct list holder variable:
list sl_hold[1] : length value 3
list sl_hold[2] : length values 5, 5
list sl_hold[3] : length values 7, 7, 7
list sl_hold[4] : length value 5
The sl_hold list values are then printed in the for loop.
<'
struct packet {
address: byte;
length: uint;
};
extend sys {
packets[7]: list of packet;
lengths: list of uint;
keep lengths == {3; 5; 5; 7; 7; 7; 5};
keep for each in packets {
.length == lengths[index];
};
run() is also {
var sl_hold: list of struct_list_holder;
sl_hold = packets.split(.length);
for each in sl_hold do {
print it.value;

Specman e Language Reference


1999-2015

1395
.

Product Version 15.1


All Rights Reserved.

};
};
};
'>

The output of the print sl_hold[i].value loop is shown below. The length field values for the
packet items are in the column on the right.
p[i].value =
item
type
0.
packet

112

p[i].value =
item
type
0.
packet
1.
packet

32
78

5
5

p[i].value =
item
type
0.
packet
1.
packet
2.
packet

172
172
25

7
7
7

p[i].value =
item
type
0.
packet

70

Example 3
The following splits the list in the preceding example at each point where the value of the expression
.length > 5 changes, that is, between 5 and 7 and between 7 and 5.
var sl_hold := sys.packets.split(.length > 5);

The struct_list_holder variable sl_hold then contains three lists:


3, 5, 5
7, 7, 7
5

Example 4
To sort the list before you split it, you can use the following syntax.
var sl_hold := sys.packets.sort(.length).split(.length);

Specman e Language Reference


1999-2015

1396

Product Version 15.1


All Rights Reserved.

See Also

get_indices() on page 1366

has() on page 1367

all() on page 1401

25.4.28 top()
Purpose
Return the last item in a list

Category
Pseudo-method

Syntax
list.top(): list-item
Syntax Example
var pk: packet;
pk = sys.packets.top();

Parameters
list

A list.

Description
Returns the last item in the list without removing it from the list. If the list is empty, an error is issued.

Example
The following example prints the contents of the last packet in the packets list.
print sys.packets.top();

See Also

pop() on page 1337

Specman e Language Reference


1999-2015

1397
.

Product Version 15.1


All Rights Reserved.

top0() on page 1398

25.4.29 top0()
Purpose
Return the first item of a list

Category
Pseudo-method

Syntax
list.top0(): list-item
Syntax Example
var pk: packet;
pk = sys.packets.top0();

Parameters
list

A list.

Description
Returns the first item in the list without removing it from the list. If the list is empty, an error is issued.
This pseudo-method can be used with pop0() to emulate queues.

Example
The following example prints the contents of the first packet in the packets list.
print sys.packets.top0();

See Also

pop0() on page 1338

top() on page 1397

Specman e Language Reference


1999-2015

1398

Product Version 15.1


All Rights Reserved.

25.4.30 unique()
Purpose
Collapse consecutive items that have the same value into one item

Category
Pseudo-method

Syntax
list.unique(select-exp: exp): list
Syntax Example
var u_list: list of l_item;
u_list = sys.l_list.unique(it.f_1);

Parameters
list

A list.

select-exp An expression. The it variable can be used to refer to the current list item, and the index
variable can be used to refer to its index number.

Description
Returns a new list of all the distinct values in list. In the new list, all consecutive occurrences of items for
which the value of exp are the same are collapsed into one item.
Note This pseudo-method was at one time named list.uniq(). The syntax and semantics of
list.unique() and list.uniq() are identical.

Example 1
In the following example, the list.unique() pseudo-method collapses the consecutive 5s and the
consecutive 7s in i_list into a single 5 and a single seven. The example prints 3, 5, 7, 5.
var i_list := {3; 5; 5; 7; 7; 7; 5};
var pl: list of int;
pl = i_list.unique(it);
print pl;

Specman e Language Reference


1999-2015

1399
.

Product Version 15.1


All Rights Reserved.

Example 2
Suppose the packets list contains seven packets with the following length field values: 3, 5, 5, 7, 7,
7, 5. The list.unique() pseudo-method collapses the consecutive packets with lengths of 5 into a single
item, and collapses the consecutive items with lengths of 7 into a single item. The pl list gets four
packets, with lengths of 3, 5, 7, and 5.
var pl: list of packet;
pl = packets.unique(.length);

Example 3
In the following example, the list.unique() pseudo-method removes any packet items with repeated
length values from the packets list after the list is sorted using the list.sort() pseudo-method.
<'
struct packet {
length: uint (bits: 8);
width: uint (bits: 8);
};
extend sys {
packets: list of packet;
run() is also {
var s_list: list of packet;
s_list= packets.sort(.length).unique(.length);
print s_list;
};
};
'>

See Also

count() on page 1357

size() on page 1388

sort() on page 1390

sort_by_field() on page 1392

all() on page 1401

25.5 Sublist Pseudo-Methods


This section describes the syntax for pseudo-methods that construct a new list from all the items in
another list that satisfy specified conditions.
The pseudo-methods in this section are:
Specman e Language Reference
1999-2015

1400

Product Version 15.1


All Rights Reserved.

all() on page 1401

all_indices() on page 1403

See Also

Pseudo-Methods Overview on page 1319

Using List Pseudo-Methods on page 1320

Converting from One Data Type to Another on page 194

25.5.1

all()

Purpose
Get all items that satisfy a condition

Category
Pseudo-method

Syntax
list.all(exp: bool): list
Syntax Example
var l_2: list of packet;
l_2 = sys.packets.all(it.length > 64);

Parameters
list

A list.

exp

A Boolean expression. The it variable can be used to refer to the current item, and the index
variable can be used to refer to its index number.

Description
Returns a list of all the items in list for which exp is TRUE. If no items satisfy the Boolean expression,
an empty list is returned.

Specman e Language Reference


1999-2015

1401
.

Product Version 15.1


All Rights Reserved.

Example 1
The following example prints 7, 9, 11, since those are the values in l_list that are greater than 5.
var l_list: list of int = {1; 3; 5; 7; 9; 11};
print l_list.all(it > 5);

Example 2
The following example creates a list named pl of all packets that have a length field value less than
5, and prints the pl list.
<'
type packet_type: [ETH, ATM];
struct packet {
length: uint (bits: 4);
ptype: packet_type;
};
extend sys {
packets: list of packet;
run() is also {
var pl: list of packet;
pl = packets.all(.length < 5);
print pl;
};
};
'>

Example 3
The following creates a list named pt of all packets that have a ptype field value of ETH, and
prints the pt list. This example uses the it is a type syntax to specify which subtype of the packet
struct to look for.
<'
type packet_type: [ETH, ATM];
struct packet {
length: uint (bits: 4);
ptype: packet_type;
};
extend sys {
packets: list of packet;
run() is also {
var pt:= packets.all(it is a ETH packet);
print pt;
};
};

Specman e Language Reference


1999-2015

1402

Product Version 15.1


All Rights Reserved.

'>

See Also

is [not] a on page 123

first() on page 1361

has() on page 1367

last() on page 1372

max() on page 1376

min() on page 1381

all_indices() on page 1403

25.5.2

all_indices()

Purpose
Get indexes of all items that satisfy a condition

Category
Pseudo-method

Syntax
list.all_indices(exp: bool): list of int
Syntax Example
var l_2: list of int;
l_2 = sys.packets.all_indices(it.length > 5);

Parameters
list

A list.

exp

A Boolean expression.

Specman e Language Reference


1999-2015

1403
.

Product Version 15.1


All Rights Reserved.

Description
Returns a list of all indexes of items in list for which exp is TRUE. If no items satisfy the Boolean
expression, an empty list is returned.

Example 1
The following example creates a list name tl that contains the index numbers of all the instr
instances in the list named i_list which have op1 field values greater than 63.
<'
type op_code: [ADD, SUB, MLT];
struct instr {
op1: int (bits: 8);
op2: int;
opcode: op_code;
};
extend sys {
i_list: list of instr;
run() is also {
var tl: list of int;
tl = i_list.all_indices(it.op1 > 63);
print tl;
};
};
'>

Results
tl =
0.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

0
1
2
3
4
8
12
28
29
30
31
33

Example 2
In the following example, the list.all_indices() pseudo-method is used to create a list named pl of the
indexes of the packets list items that are of subtype small packet.
Specman e Language Reference
1999-2015

1404

Product Version 15.1


All Rights Reserved.

<'
type pkt_type: [small, medium, large];
struct packet {
address: byte;
ptype: pkt_type;
};
extend sys {
packets: list of packet;
keep packets.size() == 10;
run() is also {
print packets;
var pl: list of int;
pl = packets.all_indices(it is a small packet);
print pl;
};
};
'>

Results
packets =
item
type

address

ptype

0.
1.
2.
3.
4.
5.
6.
7.
8.
9.

97
66
10
180
235
196
85
163
62
86

medium
large
large
medium
small
small
large
small
large
large

packet
packet
packet
packet
packet
packet
packet
packet
packet
packet
pl =
0.
4
1.
5
2.
7

Example 3
Using all_indices() on an empty list produces another empty list. Trying to use this result in a gen
keeping constraint can cause a generation contradiction error. To avoid this, you can use a check like if
!test_ix.is_empty() in the following example.
<'
struct st_eng {
v_list: list of uint (bits: 7);
Specman e Language Reference
1999-2015

1405
.

Product Version 15.1


All Rights Reserved.

ameth(): list of int is {


var test_ix: list of int;
test_ix = v_list.all_indices(it > 100);
var s_index: uint;
if !test_ix.is_empty() {
gen s_index keeping {it in test_ix};
return test_ix;
};
};
};
extend sys {
st_i: st_eng;
s_list: list of int;
run() is also {
s_list = st_i.ameth();
print s_list;
};
};
'>

Results
s_list =
0.
9
1.
20
2.
21
3.
37
4.
39
5.
44

See Also

field (for List Item) on page 1360

first_index() on page 1363

has() on page 1367

last_index() on page 1374

max_index() on page 1377

min_index() on page 1382

all() on page 1401

Specman e Language Reference


1999-2015

1406

Product Version 15.1


All Rights Reserved.

25.6 Math and Logic Pseudo-Methods


This section describes the syntax for pseudo-methods that perform arithmetic or logical operations to
compute a value using all items in a list.
The pseudo-methods in this section are:

and_all() on page 1407

average() on page 1408

or_all() on page 1410

product() on page 1411

sum() on page 1413

See Also

Pseudo-Methods Overview on page 1319

Using List Pseudo-Methods on page 1320

25.6.1

and_all()

Purpose
Compute the logical AND of all items

Category
Pseudo-method

Syntax
list.and_all(exp: bool): bool
Syntax Example
var bool_val: bool;
bool_val = m_list.and_all(it >= 1);

Parameters
list

A list.

Specman e Language Reference


1999-2015

1407
.

Product Version 15.1


All Rights Reserved.

exp

A Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns a TRUE if the given expression is true for all items in the list, or FALSE if the expression is
false for any item in the list.
Note Unlike most list pseudo-methods, and_all() is a generative (bidirectional) list pseudo-method.
For more information, see Using Bidirectional Generative List Pseudo-Methods in the Specman
Generation User Guide and the description of the -bidir_list_pseudo_methods flag in configure gen
in the Specman Command Reference.

Example
The following command prints TRUE if the length field value of all items in the packets list is
greater than 63. If any packet has a length less than or equal to 63, it prints FALSE.
print sys.packets.and_all(it.length > 63);

See Also

average() on page 1408

or_all() on page 1410

product() on page 1411

sum() on page 1413

25.6.2

average()

Purpose
Compute the average of an expression for all items

Category
Pseudo-method

Syntax
list.average(exp: int): int
Specman e Language Reference
1999-2015

1408

Product Version 15.1


All Rights Reserved.

Syntax Example
var list_ave: int;
list_ave = sys.item_list.average(it.f_1 * it.f_2);

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the integer average of the exp computed for all the items in the list. Returns UNDEF if the list is
empty.

Example 1
The following example prints 6 ((3 + 5 + 10)/3).
var a_list := {3; 5; 10};
print a_list.average(it);

Example 2
The following example prints the average value of the length fields for all the items in the packets
list.
<'
struct packet {
length: uint (bits: 4);
width: uint (bits: 4);
};
extend sys {
packets: list of packet;
run() is also {
print packets.average(it.length);
};
};
'>

See Also

and_all() on page 1407

Specman e Language Reference


1999-2015

1409
.

Product Version 15.1


All Rights Reserved.

or_all() on page 1410

product() on page 1411

sum() on page 1413

25.6.3

or_all()

Purpose
Compute the logical OR of all items

Category
Pseudo-method

Syntax
list.or_all(exp: bool): bool
Syntax Example
var bool_val: bool;
bool_val = m_list.or_all(it >= 100);

Parameters
list

A list.

exp

A Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns a TRUE if any value of the exp is true, or returns FALSE if the exp is false for every item in the
list. Returns FALSE if the list is empty.
Note Unlike most list pseudo-methods, or_all() is a generative (bidirectional) list pseudo-method.
For more information, see Using Bidirectional Generative List Pseudo-Methods in the Specman
Generation User Guide and the description of the -bidir_list_pseudo_methods flag in configure gen
in the Specman Command Reference.

Specman e Language Reference


1999-2015

1410

Product Version 15.1


All Rights Reserved.

Example 1

Example

The following command prints TRUE if the length field value of any item in the packets list is
greater than 150. If no packet has a length greater than 150, it prints FALSE.
<'
struct packet {
length: uint (bits: 4);
width: uint (bits: 4);
};
extend sys {
packets: list of packet;
run() is also {
print packets.or_all(it.length > 150);
};
};
'>

Example 2
The following code snippet generates a list of ints and a Boolean field such that Boolean field is TRUE
only if all the list elements are different than 0.:
b : bool;
l : list of int[-20..20];
keep b != l.or_all(it==0);

See Also

and_all() on page 1407

average() on page 1408

product() on page 1411

sum() on page 1413

25.6.4

product()

Purpose
Compute the product of an expression for all items

Category
Pseudo-method
Specman e Language Reference
1999-2015

1411
.

Product Version 15.1


All Rights Reserved.

Syntax
list.product(exp: int): int
Syntax Example
var list_prod: int;
list_prod = sys.item_list.product(it.f_1);

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the integer product of the exp computed over all the items in the list. Returns 1 if the list is
empty.

Example 1
The following example prints 150 (3 * 5 * 10).
var p_list := {3; 5; 10};
print p_list.product(it);

Example 2
The following example prints the product of the mlt fields in all the items in the packets list.
<'
struct packet {
mlt: uint (bits: 3);
keep mlt > 0;
};
extend sys {
packets[5]: list of packet;
run() is also {
print packets.product(it.mlt);
};
};
'>

Specman e Language Reference


1999-2015

1412

Product Version 15.1


All Rights Reserved.

See Also

and_all() on page 1407

average() on page 1408

or_all() on page 1410

sum() on page 1413

25.6.5

sum()

Purpose
Compute the sum of all items in the list.

Category
Pseudo-method

Syntax
list.sum(exp: int): int
Syntax Example
var op_sum: int;
op_sum = sys.instr_list.sum(.op1);

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the integer sum of the exp computed over all the items in the list. Returns 0 if the list is empty.
The following example prints 18 (3 + 5 + 10).
var s_list := {3; 5; 10};
print s_list.sum(it);

Specman e Language Reference


1999-2015

1413
.

Product Version 15.1


All Rights Reserved.

Note Unlike most list pseudo-methods, sum() is a generative (bidirectional) list pseudo-method. For
more information, see Using Bidirectional Generative List Pseudo-Methods in the Specman Generation
User Guide.

Example
The following example prints the sum of the length field values for all the items in the packets list.
<'
struct packet {
length: uint (bits: 4);
keep length in [1..5];
width: uint (bits: 4);
keep width in [1..5];
};
extend sys {
packets[5]: list of packet;
run() is also {
print packets.sum(it.length);
};
};
'>

See Also

Generative List Pseudo-Methods in Specman Generation User Guide

sum() (Conditional) on page 1414

and_all() on page 1407

average() on page 1408

or_all() on page 1410

product() on page 1411

25.6.6

sum() (Conditional)

Purpose
Computes the sum of all items in a list for which a given Boolean expression evaluates to TRUE.

Category
Pseudo-method
Specman e Language Reference
1999-2015

1414

Product Version 15.1


All Rights Reserved.

Syntax
list.sum(exp: int, bool-expr: bool): int
Syntax Example
l [10] : list of packet;
keep l.sum(it.sz , it.color == RED) < 2048;
keep l.sum(it.sz , it.color == BLUE) < 1024;

Parameters
list

A list.

exp

An integer expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

bool-exp

Any Boolean expression. The it variable can be used to refer to the current list item, and the
index variable can be used to refer to its index number.

Description
Returns the integer sum of the exp computed over all the items in the list for which the bool-exp returns
TRUE. Returns 0 if the list is empty.
Note Unlike most list pseudo-methods, sum() is a generative (bidirectional) list pseudo-method. For
more information, see Using Bidirectional Generative List Pseudo-Methods in the Specman Generation
User Guide.

Example 1
The following example generates a list of 10 packets such that (1) the sum of all RED packets sizes will
be less than 2K and (2) the sum of all the BLUE packets sizes will be less than 1K.
struct packet {
color: [RED, BLUE];
sz: uint;
};
extend sys {
l [10] : list of packet;
keep l.sum(it.sz , it.color == RED) < 2048;
keep l.sum(it.sz , it.color == BLUE) < 1024;
};

Specman e Language Reference


1999-2015

1415
.

Product Version 15.1


All Rights Reserved.

Example 2
The following example illustrates how the generator evaluates a conditional sum() expression, which is
that it first evaluates the Boolean expression for all items on the list and then evaluates the integer
expression only for those list items for which the Boolean expression is TRUE.
extend sys {
bool_func(i:int):bool is {
out("bool_func(",i,")");
return i%2==0;
};
int_func(i:int):int is {
out("int_func(",i,")");
return i;
};
run() is also {
var l : list of int = {0;1;2;3;4;5};
print l.sum(int_func(it), bool_func(it));
};
};

Running the above example prints the results shown below. As you can see, Specman evaluates the
Boolean expression for all list items and the integer expressions for only the first (0), third (2) and fifth
(4) items (for which the Boolean expression evaluates to TRUE).
bool_func(0)
int_func(0)
bool_func(1)
bool_func(2)
int_func(2)
bool_func(3)
bool_func(4)
int_func(4)
bool_func(5)
6

See Also

Generative List Pseudo-Methods in Specman Generation User Guide

sum() on page 1413

and_all() on page 1407

average() on page 1408

or_all() on page 1410

product() on page 1411

Specman e Language Reference


1999-2015

1416

Product Version 15.1


All Rights Reserved.

25.7 List CRC Pseudo-Methods


This section describes the syntax for pseudo-methods that perform CRC (cyclic redundancy check)
functions on lists.
The pseudo-methods in this section are:

crc_8() on page 1417

crc_32() on page 1419

crc_32_flip() on page 1421

See Also

Pseudo-Methods Overview on page 1319

Using List Pseudo-Methods on page 1320

25.7.1

crc_8()

Purpose
Compute the CRC8 of a list of bits or a list of bytes

Category
Pseudo-method

Syntax
list.crc_8(from-byte: int, num-bytes: int): int
Syntax Example
print b_data.crc_8(2,4);

Parameters
list

A list of bits or bytes.

from-byte

The index number of the starting byte.

num-bytes

The number of bytes to use.

Specman e Language Reference


1999-2015

1417
.

Product Version 15.1


All Rights Reserved.

Description
Reads the list byte-by-byte and returns the integer value of the CRC8 function of a list of bits or bytes.
Only the least significant byte (LSB) is used in the result.
The CRC is computed starting with the from-byte, for num-bytes. If from-byte or from-byte+num-bytes
is not in the range of the list, an error is issued.

Note
The algorithm for computing CRC8 is specific for the ATM HEC (Header Error Control) computation.
The code used for HEC is a cyclic code with the following generating polynomial:
x**8 + x**2 + x + 1

Example
In the example below, the e_crc variable gets the CRC8 of the bytes 2, 3, 4, and 5 in the list named
b_data.
<'
extend sys {
run() is also {
var b_data: list of byte = {0xff;0xaa;0xdd;0xee;0xbb;0xcc};
print b_data.crc_8(2,4);
};
};
'>

Results
b_data.crc_8(2,4) = 0x63

See Also

crc_32() on page 1419

crc_32_flip() on page 1421

product() on page 1411

sum() on page 1413

pack() on page 1059

unpack() on page 1064

Specman e Language Reference


1999-2015

1418

Product Version 15.1


All Rights Reserved.

25.7.2

crc_32()

Purpose
Compute the CRC32 of a list of bits or a list of bytes

Category
Pseudo-method

Syntax
list.crc_32(from-byte: int, num-bytes: int): int
Syntax Example
print b_data.crc_32(2,4);

Parameters
list

A list of bits or bytes.

from-byte

The index number of the starting byte.

num-bytes

The number of bytes to use.

Description
Reads the list byte-by-byte and returns the integer value of the CRC32 function of a list of bits or bytes.
Only the least significant word is used in the result.
The CRC is computed starting with the from-byte, for num-bytes. If from-byte or from-byte+num-bytes
is not in the range of the list, an error is issued.

Note
The algorithm for computing CRC32 generates a 32-bit CRC that is used for messages up to 64
kilobytes in length. Such a CRC can detect 99.999999977% of all errors. The generator polynomial for
the 32-bit CRC used for both Ethernet and token ring is:
x**32 + x**26 + x**23 + x**22 + x**16 + x**12 + x**11 + x**10 + x**8 + x**7 + x**5 + x**4
+x**2 + x + 1

Specman e Language Reference


1999-2015

1419
.

Product Version 15.1


All Rights Reserved.

Example 1
In the example below, the b_data variable gets the packed packet struct instance as a list of bytes,
and the CRC32 of bytes 2, 3, 4, and 5 of b_data is printed.
<'
struct packet {
%byte_1: byte;
%byte_2: byte;
%byte_3: byte;
%byte_4: byte;
%byte_5: byte;
%byte_6: byte;
};
extend sys {
packet;
run() is also {
var b_data: list of byte = pack(NULL, me.packet);
print b_data.crc_32(2,4);
};
};
'>

Example 2
In the example below, the CRC32 value is calculated for the data field value. The is_good_crc()
method checks the value and returns TRUE if it is good, FALSE if it is bad.
<'
struct packet {
%data: list of byte;
!%crc: uint;
packed: list of byte;
run() is also {
crc = (data.crc_32(0, data.size()) ^ 0xffff_ffff);
packed = pack(packing.low, me);
};
is_good_crc(): bool is {
result = (packed.crc_32(0, packed.size()) ==
0xffff_ffff);
};
};
extend sys {
packets: list of packet;
run() is also {
for each in packets {
outf("frame %d ", index);
print it.is_good_crc();
Specman e Language Reference
1999-2015

1420

Product Version 15.1


All Rights Reserved.

};
};
};
'>

See Also

crc_8() on page 1417

crc_32_flip() on page 1421

product() on page 1411

sum() on page 1413

pack() on page 1059

unpack() on page 1064

25.7.3

crc_32_flip()

Purpose
Compute the CRC32 of a list of bits or a list of bytes, flipping the bits

Category
Pseudo-method

Syntax
list.crc_32_flip(from-byte: int, num-bytes: int): int
Syntax Example
print b_data.crc_32_flip(2,4);

Parameters
list

A list of bits or bytes.

from-byte

The index number of the starting byte.

num-bytes

The number of bytes to use.

Specman e Language Reference


1999-2015

1421
.

Product Version 15.1


All Rights Reserved.

Description
Reads the list byte-by-byte and returns the integer value of the CRC32 function of a list of bits or bytes,
with the bits flipped. Only the least significant word is used in the result.
The CRC is computed starting with the from-byte, for num-bytes. If from-byte or from-byte+num-bytes
is not in the range of the list, an error is issued.
The bits are flipped as follows:
1.

The bits inside each byte of the input are flipped.

2.

The bits in the result are flipped.

Example
In the example below, the tc_crc variable gets the CRC32 of the bytes 2, 3, 4, and 5 in the list named
b_data, with the bits flipped.
<'
struct packet {
%byte_1: byte;
%byte_2: byte;
%byte_3: byte;
%byte_4: byte;
%byte_5: byte;
%byte_6: byte;
};
extend sys {
packet;
run() is also {
var b_data: list of byte = pack(NULL, me.packet);
print b_data.crc_32_flip(2,4);
};
};
'>

See Also

crc_8() on page 1417

crc_32() on page 1419

product() on page 1411

sum() on page 1413

pack() on page 1059

unpack() on page 1064

Specman e Language Reference


1999-2015

1422

Product Version 15.1


All Rights Reserved.

25.8 Keyed List Pseudo-Methods


This section describes the syntax for pseudo-methods that can be used only on keyed lists.
Keyed lists are list in which each item has a key associated with it. For a list of structs, the key typically
is the name of a particular field in each struct. Each unique value for that field may be used as a key. For
a list of scalars, the key can be the it variable referring to each item.
While creating a keyed list, you must ensure that the key has a unique value for each item. Once the list
is created, you cannot update the value of the key itself.
Keyed lists can be searched quickly, by searching on a key value.
This section contains descriptions of pseudo-methods that can only be used for keyed lists. Using one of
these methods on a regular list results in an error.
The pseudo-methods in this section are:

key() on page 1423

key_index() on page 1427

key_exists() on page 1428

See Also

Pseudo-Methods Overview on page 1319

Using List Pseudo-Methods on page 1320

list(key) of on page 235

25.8.1

key()

Purpose
Get the item that has a particular key

Category
Pseudo-method

Syntax
list.key(key-exp: exp): list-item

Specman e Language Reference


1999-2015

1423
.

Product Version 15.1


All Rights Reserved.

Syntax Example
var loc_list_item: location;
var i_key: uint;
i_key = 5;
loc_list_item = locations.key(i_key);

Parameters
list

A keyed list.

key-exp

The key of the item that is to be returned.

Description
Returns the list item that has the specified key, or NULL if no item with that key exists in the list.
For a list of scalars, a value of zero is returned if there is no such item. Since zero might be confused
with a found value, it is not advisable to use zero as a key for scalar lists.
Note If there is more than one item in the list with the same key value, the behavior of this
pseudo-method is undefined.

Example 1
The following example uses a list of integers for which the key is the item itself. This example prints 5.
var l_list: list(key: it) of int = {5; 4; 3; 2; 1};
print l_list.key(5);

Example 2
In the following example, the mklist() method generates a list of 10 location instances with even
numbered address from 2 to 20. The locations list is a list of location instances with address as its
key. The l_item variable gets the locations list item that has an address value of 6. If there is no
item in the list with an address of 6, the locations.key() pseudo-method returns NULL.
<'
struct location {
address: int;
value: int;
};
struct l_s {
mklist() is {
var l: location;
Specman e Language Reference
1999-2015

1424

Product Version 15.1


All Rights Reserved.

for i from 1 to 10 do {
gen l keeping {it.address == 2*i};
sys.locations.add(l);
};
};
};
extend sys {
l_s;
!locations: list(key: address) of location;
run() is also {
l_s.mklist();
print locations;
var l_item: location;
l_item = locations.key(6);
print l_item;
};
};
'>

Results
locations =
item
type

address

value

0.
1.
2.
3.
4.
5.
6.
7.
8.
9.

location
2
-396796955
location
4
1796592623
location
6
2081332301
location
8
-15822625*
location
10
116159091
location
12
-15052943*
location
14
1128419469
location
16
-20275240*
location
18
-508036604
location
20
116597347
l_item = location-@0: location
----------------------------------------------@kl_2
0
address:
6
1
value:
2081332301

Example 3
The following example shows how to use a keyed list on the lefthand side of assignment. The mklist()
method generates a list of 10 location instances with even-numbered address values from 2 to 20.
The locations list is a list of location instances with address as its key. The l_item variable is a
location instance which is generated with a constraint to keep its value equal to 100000. That location
instances value field is then assigned to the locations list item that has the address key value of 6.
Specman e Language Reference
1999-2015

1425
.

Product Version 15.1


All Rights Reserved.

<'
struct location {
address: int;
value: int;
};
struct l_s {
mklist() is {
var l: location;
for i from 1 to 10 do {
gen l keeping {it.address == 2*i};
sys.locations.add(l);
};
};
};
extend sys {
l_s;
!locations: list(key: address) of location;
run() is also {
l_s.mklist();
var l_item: location;
gen l_item keeping {it.value == 100000};
print l_item;
locations.key(6).value = l_item.value;
print locations.key(6);
};
};
'>

Results
l_item = location-@0: location
----------------------------------------------@kl_assign_3
0
address:
-513087844
1
value:
100000
locations.key(6) = location-@1: location
----------------------------------------------@kl_assign_3
0
address:
6
1
value:
100000

See Also

key_index() on page 1427

key_exists() on page 1428

list(key) of on page 235

Specman e Language Reference


1999-2015

1426

Product Version 15.1


All Rights Reserved.

25.8.2

key_index()

Purpose
Get the index of an item that has a particular key

Category
Pseudo-method

Syntax
list.key_index(key-exp: exp): int
Syntax Example
var loc_list_ix: int;
loc_list_ix = locations.key_index(i);

Parameters
list

A keyed list.

key-exp

The key of the item for which the index is to be returned.

Description
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.
Note If there is more than one item in the list with the same key value, the behavior of this
pseudo-method is undefined.

Example 1
The following example uses a list of integers for which the key is the item itself. This example prints 1,
since that is the index of the list item with a value of 2.
var l_list: list(key: it) of int = {1; 2; 3; 4; 5};
print l_list.key_index(2);

Specman e Language Reference


1999-2015

1427
.

Product Version 15.1


All Rights Reserved.

Example 2
The locations.key_index() pseudo-method in the following gets the index of the item in the locations
list that has an address of 9, if any item in the list has that address.
<'
struct location {
address: int;
value: int;
};
extend sys {
!locations: list(key: address) of location;
locs: list of location;
post_generate() is also {
for each in locs {
locations.add(it);
};
};
run() is also {
var l_ix: int;
l_ix = locations.key_index(9);
if l_ix != UNDEF {print locations[l_ix].value}
else {outf("key_index %d does not exist\n", 9)};
};
};
'>

See Also

key() on page 1423

key_exists() on page 1428

list(key) of on page 235

25.8.3

key_exists()

Purpose
Check that a particular key is in a list

Category
Pseudo-method

Specman e Language Reference


1999-2015

1428

Product Version 15.1


All Rights Reserved.

Syntax
list.key_exists(key-exp: exp): bool
Syntax Example
var loc_list_k: bool;
var i:= 5;
loc_list_k = locations.key_exists(i);

Parameters
list

A keyed list.

key

The key that is to be searched for.

Description
Returns TRUE if the key exists in the list, or FALSE if it does not.
Note If there is more than one item in the list with the same key value, the behavior of this
pseudo-method is undefined.

Example 1
The following example uses a list of integers for which the key is the item itself. The first print action
prints TRUE, since 2 exists in the list. The second print action prints FALSE, since 7 does not exist in
the list.
var l_list: list(key: it) of int = {1; 2; 3; 4; 5};
print l_list.key_exists(2);
print l_list.key_exists(7);

Example 2
The locations.key_exists() pseudo-method in the following example returns TRUE to k if there is an
item in the locations list that has a key value of 30, or FALSE if there is no such item.
<'
struct location {
address: int;
value: int;
};
extend sys {
!locations: list(key: address) of location;
locs: list of location;
Specman e Language Reference
1999-2015

1429
.

Product Version 15.1


All Rights Reserved.

post_generate() is also {
for each in locs {
locations.add(it);
};
};
run() is also {
var k: bool;
k = locations.key_exists(30);
if k {outf("key %d exists\n", 30)}
else {outf("key %d does not exist\n", 30)};
};
};
'>

See Also

key() on page 1423

key_index() on page 1427

list(key) of on page 235

Specman e Language Reference


1999-2015

1430

Product Version 15.1


All Rights Reserved.

26

Set Pseudo-Methods

A number of pseudo-methods can be used on e sets. They are documented according to purpose, in the
following topics:

Fundamental Set Operation Pseudo-Methods on page 1431

Set Size Pseudo-Methods on page 1434

Set Boundaries Pseudo-Methods on page 1438

Set Pseudo-Methods for Continuous Ranges on page 1448

26.1 Fundamental Set Operation Pseudo-Methods


This section describes set operation pseudo-methods that are fundamental for constructing new sets
from given sets. It includes the following:

union(set) on page 1431

intersect(set) on page 1432

diff(set) on page 1433

See Also

The set Type on page 142

26.1.1

union(set)

Purpose
Returns the set containing all of the members that belong to either of two sets of integers.

Specman e Language Reference


1999-2015

1431
.

Product Version 15.1


All Rights Reserved.

Category
Set pseudo-method

Syntax
set1.union(set2:set):set

Parameters
set1, set2

An expression of type set.

Description
Returns the set of all elements that are members of either set1 or set2.

Example
struct s {
foo() is {
var s1: set = [1..4];
var s2: set = [3..7]
var s3: set;
s3 = s1.union(s2); // s3 = [1..7]
};
};

26.1.2

intersect(set)

Purpose
Returns the set of all of the members that belong to both of two sets of integers.

Category
Set pseudo-method

Syntax
set1.intersect(set2:set):set
Specman e Language Reference
1999-2015

1432

Product Version 15.1


All Rights Reserved.

Parameters
set1, set2

An expression of type set.

Description
Returns the set of all elements that are members of both set1 and set2.

Example
struct s {
foo() is {
var s1: set = [1..4];
var s2: set = [3..7]
var s3: set;
s3 = s1.intersect(s2); // s3 = [3..4]
};
};

26.1.3

diff(set)

Purpose
Subtract one set from another.

Category
Set pseudo-method

Syntax
set1.diff(set2:set):set

Parameters
set1, set2

An integer expression of type set.

Description
Returns the set of all elements that are members of set1, but not members of set2.
Specman e Language Reference
1999-2015

1433
.

Product Version 15.1


All Rights Reserved.

Example
struct s {
foo() is {
var s1: set = [1..4];
var s2: set = [3..7]
var s3: set;
s3 = s1.diff(s2); // s3 = [1..2]
};
};

26.2 Set Size Pseudo-Methods


This group of pseudo-methods includes the following:

set.size() on page 1434

set.uint_size() on page 1435

set.size_is_uint() on page 1437

See Also

The set Type on page 142

26.2.1

set.size()

Purpose
Return the size of the set as an unbound integer.

Category
Set pseudo-method

Syntax
set.size(): int(bits:*)

Specman e Language Reference


1999-2015

1434

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
Return the size of the expression of type set as an unbounded interger.

Example
Example
!interest_set: set;
!full_inclusion: list of set;
!large_intersect: list of set;
!small_intersect: list of set;
!no_intersect: list of set;
store_set(the_set: set) is {
var s:= interest_set.intersect(the_set);
if s == interest_set {
full_inclusion.add(the_set);
}
else if s == [] {
no_intersect.add(the_set);
}
else if s.size() > (interest_set.size() / 2) {
large_intersect.add(the_set);
}
else {
small_intersect.add(the_set);
};
};

26.2.2

set.uint_size()

Purpose
Return the size of the set as an uint.

Specman e Language Reference


1999-2015

1435
.

Product Version 15.1


All Rights Reserved.

Category
Set pseudo-method

Syntax
set.uint_size(): uint

Parameters
set

Expression of type set.

Description
This pseudo-method returns the size of the expression of type set as an uint. It can be used instead of
set.size() for better performance; however, it will result in an error if the set size exceeds MAX_UINT.
Therefore, use pseudo-method set.size_is_uint() to check if it is safe to use this pseudo-method.

Example
!huge_sets: list of set;
!large_sets: list of set;
!small_sets: list of set;
store_set(the_set: set) is {
if not the_set.size_is_uint() {
huge_sets.add(the_set);
}
else {
var size := the_set.uint_size();
if size > SMALL_SET_SIZE_LIMIT {
large_sets.add(the_set);
}
else {
small_sets.add(the_set);
};
};
};

Specman e Language Reference


1999-2015

1436

Product Version 15.1


All Rights Reserved.

26.2.3

set.size_is_uint()

Purpose
Indicates if it is safe to use set.uint_size().

Category
Set pseudo-method

Syntax
set.size_is_uint(): bool

Parameters
set

Expression of type set.

Description
This method will return TRUE if it is safe to use set.uint_size() (that is, if the set size does not exceed
MAX_UINT), and FALSE if using set.uint_size() will cause an error.

Example
!large_sets: list of set;
!small_sets: list of set;
store_set(the_set: set) is {
if not the_set.size_is_uint() {
error("Set ", the_set, " is too large: ", the_set.size());
}
else {
var size := the_set.uint_size();
if size > SMALL_SET_SIZE_LIMIT {
large_sets.add(the_set);
}
else {
small_sets.add(the_set);
};
};
};

Specman e Language Reference


1999-2015

1437
.

Product Version 15.1


All Rights Reserved.

26.3 Set Boundaries Pseudo-Methods


This group of pseudo-methods includes the following:

set.min() on page 1438

set.max() on page 1439

set.int_min() on page 1440

set.int_max() on page 1441

set.min_is_int() on page 1442

set.max_is_int() on page 1443

set.uint_min() on page 1444

set.uint_max() on page 1445

set.min_is_uint() on page 1446

set.max_is_uint() on page 1447

See Also

The set Type on page 142

26.3.1

set.min()

Purpose
Return the minimum value of set as an integer of unlimited size.

Category
Set pseudo-method

Syntax
set.min(): int(bits:*)

Specman e Language Reference


1999-2015

1438

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
Returns the minimum value of the expression of type set as an integer of unlimited size. If set is empty,
it produces an error.

Example
!dense_sets: list of set;
!sparse_sets: list of set;
store_set(the_set: set) is {
if the_set != [] {
if the_set.size().as_a(real)/(the_set.max() the_set.min()) > 0.5 {
dense_sets.add(the_set);
}
else {
sparse_sets.add(the_set);
};
};
};

26.3.2

set.max()

Purpose
Return the maximum value of set as an integer of unlimited size.

Category
Set pseudo-method

Syntax
set.max(): int(bits:*)

Specman e Language Reference


1999-2015

1439
.

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
Returns the maximum value of the expression of type set as an integer of unlimited size. If set is empty,
it produces an error.

Example
!dense_sets: list of set;
!sparse_sets: list of set;
store_set(the_set: set) is {
if the_set != [] {
if the_set.size().as_a(real)/(the_set.max() the_set.min()) > 0.5 {
dense_sets.add(the_set);
}
else {
sparse_sets.add(the_set);
};
};
};

26.3.3

set.int_min()

Purpose
Return the minimum value of set as int.

Category
Set pseudo-method

Syntax
set.int_min(): int

Specman e Language Reference


1999-2015

1440

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
Returns the minimum value of the expression of type set as int. It produces an error if set is empty, or if
the value is less than MIN_INT or greater than MAX_INT.

Example
!dense_int_sets: list of set;
!sparse_int_sets: list of set;
store_int_set(the_set: set) is {
if the_set.min_is_int() and the_set.max_is_int() {
if the_set.uint_size().as_a(real)/(the_set.int_max() the_set.int_min()) > 0.5 {
dense_int_sets.add(the_set);
}
else {
sparse_int_sets.add(the_set);
};
};
};

26.3.4

set.int_max()

Purpose
Return the maximum value of set as int.

Category
Set pseudo-method

Syntax
set.int_max(): int

Specman e Language Reference


1999-2015

1441
.

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
Returns the maximum value of the expression of type set as int. It produces an error if set is empty, or if
the value is less than MIN_INT or greater than MAX_INT.

Example
!dense_int_sets: list of set;
!sparse_int_sets: list of set;
store_int_set(the_set: set) is {
if the_set.min_is_int() and the_set.max_is_int() {
if the_set.uint_size().as_a(real)/(the_set.int_max() the_set.int_min()) > 0.5 {
dense_int_sets.add(the_set);
}
else {
sparse_int_sets.add(the_set);
};
};
};

26.3.5

set.min_is_int()

Purpose
Indicates if it is safe to use set.int_min().

Category
Set pseudo-method

Syntax
set.min_is_int(): bool

Specman e Language Reference


1999-2015

1442

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
This method will return TRUE if it is safe to use set.int_min() and FALSE if it will cause an error.

Example
!dense_int_sets: list of set;
!sparse_int_sets: list of set;
store_int_set(the_set: set) is {
if the_set.min_is_int() and the_set.max_is_int() {
if the_set.uint_size().as_a(real)/(the_set.int_max() the_set.int_min()) > 0.5 {
dense_int_sets.add(the_set);
}
else {
sparse_int_sets.add(the_set);
};
};
};

26.3.6

set.max_is_int()

Purpose
Indicates if it is safe to use set.int_max().

Category
Set pseudo-method

Syntax
set.max_is_int(): bool

Specman e Language Reference


1999-2015

1443
.

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
This method will return TRUE if it is safe to use set.int_max() and FALSE if it will cause an error.

Example
!dense_int_sets: list of set;
!sparse_int_sets: list of set;
store_int_set(the_set: set) is {
if the_set.min_is_int() and the_set.max_is_int() {
if the_set.uint_size().as_a(real)/(the_set.int_max() the_set.int_min()) > 0.5 {
dense_int_sets.add(the_set);
}
else {
sparse_int_sets.add(the_set);
};
};
};

26.3.7

set.uint_min()

Purpose
Return the minimum value of set as unint.

Category
Set pseudo-method

Syntax
set.uint_min(): int

Specman e Language Reference


1999-2015

1444

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
Returns the minimum value of the expression of type set as uint. It produces an error if set is empty, or
if the value is negative or greater than MAX_UINT.

Example
!dense_uint_sets: list of set;
!sparse_uint_sets: list of set;
store_uint_set(the_set: set) is {
if the_set.min_is_uint() and the_set.max_is_uint() {
if the_set.uint_size().as_a(real)/(the_set.uint_max() the_set.uint_min()) > 0.5 {
dense_uint_sets.add(the_set);
}
else {
sparse_uint_sets.add(the_set);
};
};
};

26.3.8

set.uint_max()

Purpose
Return the maximum value of the expression of set as unint.

Category
Set pseudo-method

Syntax
set.uint_max(): int

Specman e Language Reference


1999-2015

1445
.

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
Returns the maximum value of the expression of type set as uint. It produces an error if set is empty, or
if the value is negative or greater than MAX_UINT.

Example
!dense_uint_sets: list of set;
!sparse_uint_sets: list of set;
store_uint_set(the_set: set) is {
if the_set.min_is_uint() and the_set.max_is_uint() {
if the_set.uint_size().as_a(real)/(the_set.uint_max() the_set.uint_min()) > 0.5 {
dense_uint_sets.add(the_set);
}
else {
sparse_uint_sets.add(the_set);
};
};
};

26.3.9

set.min_is_uint()

Purpose
Indicates if it is safe to use set.uint_min().

Category
Set pseudo-method

Syntax
set.min_is_uint(): bool

Specman e Language Reference


1999-2015

1446

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
This method will return TRUE if it is safe to use set.uint_min() and FALSE if it will cause an error.

Example
!dense_uint_sets: list of set;
!sparse_uint_sets: list of set;
store_uint_set(the_set: set) is {
if the_set.min_is_uint() and the_set.max_is_uint() {
if the_set.uint_size().as_a(real)/(the_set.uint_max() the_set.uint_min()) > 0.5 {
dense_uint_sets.add(the_set);
}
else {
sparse_uint_sets.add(the_set);
};
};
};

26.3.10 set.max_is_uint()
Purpose
Indicates if it is safe to use set.uint_max().

Category
Set pseudo-method

Syntax
set.max_is_uint(): bool

Specman e Language Reference


1999-2015

1447
.

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

Description
This method will return TRUE if it is safe to use set.uint_max() and FALSE if it will cause an error.

Example
!dense_uint_sets: list of set;
!sparse_uint_sets: list of set;
store_uint_set(the_set: set) is {
if the_set.min_is_uint() and the_set.max_is_uint() {
if the_set.uint_size().as_a(real)/(the_set.uint_max() the_set.uint_min()) > 0.5 {
dense_uint_sets.add(the_set);
}
else {
sparse_uint_sets.add(the_set);
};
};
};

26.4 Set Pseudo-Methods for Continuous Ranges


This group of pseudo-methods includes the following:

set.get_all_ranges() on page 1448

set.collect_all_ranges() on page 1449

set.get_range() on page 1450

set.get_range_below() on page 1451

set.get_range_above() on page 1452

26.4.1

set.get_all_ranges()

Purpose
Returns a list of all continuous ranges of the set.

Specman e Language Reference


1999-2015

1448

Product Version 15.1


All Rights Reserved.

Category
Set pseudo-method0

Syntax
set.get_all_ranges(): list of set

Parameters
set

Expression of type set.

Description
This set pseudo-method returns a list of all continuous ranges of the set. For an empty set, it returns an
empty list.

Example
If the set contains the following:
[0, 3..4, 7..9, 15]

this set pseudo-method will return a list with the values:


{[0]; [3..4]; [7..9]; [15]}

26.4.2

set.collect_all_ranges()

Purpose
Puts all continuous ranges of the set in a buffer list that can be reused.

Category
Set pseudo-method

Syntax
set.collect_all_ranges(buff: list of set)

Specman e Language Reference


1999-2015

1449
.

Product Version 15.1


All Rights Reserved.

Parameters
set

Expression of type set.

buff

Name of the buffer list.

Description
This set pseudo-method puts all continuous ranges of the set into a buffer that can be reused. For an
empty set, the buffer list is empty after the call.

Example
If the set contains the following:
[0, 3..4, 7..9, 15]

this set pseudo-method will fill the buffer with the values:
{[0]; [3..4]; [7..9]; [15]}

26.4.3

set.get_range()

Purpose
If a specified number is in a set, returns the continuous range that contains the number.

Category
Set pseudo-method

Syntax
set.get_range(num: <integer type>): set

Parameters
set

Expression of type set.

num

Number (of any signed or unsigned integer type) to search for in the set.

Specman e Language Reference


1999-2015

1450

Product Version 15.1


All Rights Reserved.

Description
For a specified number (num), if the number in the set, this set pseudo-method returns the continuous
range that contains the number; otherwise it returns an empty set.

Example
If the specified number is 8, and the set contains the following:
[0, 3..4, 7..9, 15]

this set pseudo-method will return the value:


[7..9]

26.4.4

set.get_range_below()

Purpose
Returns the continuous range that contains the specified number, or (if no range contains the number)
returns the closest range containing numbers less than the specified number.

Category
Set pseudo-method

Syntax
set.get_range_below(num: <integer type>): set

Parameters
set

Expression of type set.

num

Number (of any signed or unsigned integer type) to search for in the set.

Description
For a specified number (num), if the number is in the set, this set pseudo-method returns the continuous
range that contains that number; otherwise if there are ranges containing numbers less than num, it
returns the one closest to num. And if num is less than all the numbers in the set, it returns an empty set.
Specman e Language Reference
1999-2015

1451
.

Product Version 15.1


All Rights Reserved.

Example
If the specified number is 6, and the set contains the following:
[0, 3..4, 7..9, 15]

this set pseudo-method will return the value:


[3..4]

26.4.5

set.get_range_above()

Purpose
Returns the continuous range that contains the specified number, or (if no range contains the number)
returns the closest range containing numbers greater than the specified number.

Category
Set pseudo-method

Syntax
set.get_range_above(num: <integer type>): set

Parameters
set

Expression of type set.

num

Number (of any signed or unsigned integer type) to search for in the set.

Description
For a specified number (num), if the number is in the set, this set pseudo-method returns the continuous
range that contains that number; otherwise if there are ranges containing numbers greater than num, it
returns the one closest to num. And if num is greater than all the numbers in the set, it returns an empty
set.

Example
If the specified number is 10, and the set contains the following:
Specman e Language Reference
1999-2015

1452

Product Version 15.1


All Rights Reserved.

[0, 3..4, 7..9, 15]

this set pseudo-method will return the value:


[15]

Specman e Language Reference


1999-2015

1453
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

1454

Product Version 15.1


All Rights Reserved.

27

Predefined Routines

Predefined routines are e macros that look like methods. The distinguishing characteristics of predefined
routines are:

They are not associated with any particular struct

They share the same namespace for user-defined routines and global methods

They cannot be modified or extended with the is only, is also or is first constructs

They have no debug information

The following sections describe the predefined routines:

Struct ID Routine on page 1456

Deep Copy and Compare Routines on page 1457

Arithmetic Routines on page 1469

Routines for Random Distribution of Numbers on page 1481

Routines Supporting the real Type on page 1482

Bitwise Routines on page 1484

String Routines on page 1487

Macro-Related Routines on page 1520

Output Routines on page 1524

Configuration Routines on page 1530

Agent-Related Routine on page 1543

Specman Command Routine on page 1544

OS Interface Routines on page 1545

File Routines on page 1555

On-the-Fly Garbage Collection Routine on page 1608

Specman e Language Reference


1999-2015

1455
.

Product Version 15.1


All Rights Reserved.

Calling Predefined Routines on page 1610

See Also

Simulation-Related Routines on page 900

Invoking Methods on page 535

Chapter 23 Predefined Methods

27.1 Struct ID Routine


27.1.1

sn_unique_id_for_struct()

Purpose
Returns a unique ID for the given struct instance

Category
Predefined routine

Syntax
sn_unique_id_for_struct(instance : base_struct): int
Syntax Example
var id:= sn_unique_id_for_struct(s);

Parameter
instance

The name of the struct.

Description
Returns a unique ID for the specified struct instance.

Example
Suppose you want to track the structs you have encountered. A possible implementation could use a
keyed list:
Specman e Language Reference
1999-2015

1456

Product Version 15.1


All Rights Reserved.

!l: list (key:it) of base_struct;


saw(s: base_struct) is {
if not was_seen(s) {
l.add(s);
};
};
was_seen(s: base_struct): bool is {
result = l.key_exists(s);
};

However this approach has several drawbacks:

It allocates a pointer and a hash entry for every struct that is seen.

The structs are never freed by the garbage collection.

A much less memory intensive solution would to use the sn_unique_id_for_struct() routine:
!ids: list of bit;
saw(s: base_struct) is {
var id:= sn_unique_id_for_struct(s);
if (id >= ids.size()) {
ids.resize(id+1, TRUE, 0, TRUE);
};
ids[id] = 1;
};
was_seen(s: base_struct): bool is {
var id:= sn_unique_id_for_struct(s);
result = id < ids.size() && ids[id] == 1;
};

27.2 Deep Copy and Compare Routines


The following routines perform recursive copies and comparisons of nested structs and lists:

deep_copy() on page 1458

deep_compare() on page 1461

deep_compare_physical() on page 1466

Specman e Language Reference


1999-2015

1457
.

Product Version 15.1


All Rights Reserved.

27.2.1

deep_copy()

Purpose
Make a recursive copy of a type and its descendants

Category
Predefined routine

Syntax
deep_copy(struct-inst: exp): struct instance
Syntax Example
var pmv: packet = deep_copy(sys.pmi);

Parameters
exp

An e expression that returns a struct instance.

Description
Returns a deep, recursive copy of the struct instance. This routine descends recursively through the
fields of a struct and its descendants, copying each field by value, copying it by reference, or ignoring it,
depending on the deep_copy attribute set for that field.
The return type of deep_copy() is the same as the declared type of the struct instance.
The following table details how the copy is made, depending on the type of the field and the deep_copy
attribute (normal, reference, ignore) set for that field. For an example of how field attributes affect
deep_copy(), see attribute field on page 248.
Field Type/
Attribute
scalar

Normal

Reference

Ignore

The new field holds a copy of


the original value.

The new field holds a


copy of the original
value.

The new field holds a


copy of the original
value.

Specman e Language Reference


1999-2015

1458

Product Version 15.1


All Rights Reserved.

Field Type/
Attribute

Normal

Reference

Ignore

string

The new field holds a copy of


the original value.

The new field holds a


copy of the original
value.

The new field holds a


copy of the original
value.

scalar list

A new list is allocated with


the same size and same
elements as the original list.

The new list field


holds a copy of the
original list pointer. 1

A new list is allocated


with zero size.

struct

A new struct instance with the


same type as the original
struct is allocated. Each field
is copied or ignored,
depending on its deep_copy
attribute.

The new struct field


holds a pointer to the
original struct. 1

A new struct instance


is allocated and it is
NULL.

list of structs

A new list is allocated with


the same number of elements
as the original list.

The new list field


holds a copy of the
original list pointer. 1

A new list is allocated


with zero size.

New struct instances are also


allocated and each field in
each struct is copied or
ignored, depending on its
deep_copy attribute.
1. If the list or struct that is pointed to is duplicated (possibly because another field with
a normal attribute is also pointing to it) the pointer in this field is updated to point to
the new instance. This duplication applies only to instances duplicated by the
deep_copy() itself, and not duplications made by the extended/overridden copy()
method.

Notes

A deep copy of a scalar field (numeric, Boolean, enumerated) or a string field is the same as a shallow
copy performed by a call to copy().
A struct or list is duplicated no more than once during a single call to deep_copy().
If there is more than one reference inside the deep copy graph to a struct or list instance, and that
instance is duplicated by the call to deep_copy(), every field inside the deep copy graph that
referred to the original instance is updated to point to the new instance. A deep copy graph is the
imaginary directed graph created by traversing the structs and lists duplicated, where its nodes are
the structs or lists, and its edges are deep references to other structs or lists.

Specman e Language Reference


1999-2015

1459
.

Product Version 15.1


All Rights Reserved.

The copy() method of the type is called by deep_copy().


The structs copy() method is called before its descendants are deep copied. If the default copy()
method is overwritten or extended, this new version of the method is used.

You should apply the reference attribute to fields that store shared data and to fields that are
backpointers (pointers to the parent struct). Shared data in this context means data shared between
objects inside the deep copy graph and objects outside the deep copy graph.

Example
<'
struct packet {
header: header;
data[10]: list of byte;
protocol: [ATM, ETH, IEEE];
};
struct header {
code: uint;
};
extend sys {
pmi: packet;
m1() is {
var pmv: packet = deep_copy(sys.pmi);
pmv.data[0] = 0xff;
pmv.header.code = 0xaa;
pmv.protocol = IEEE;
print pmi.data[0], pmi.header.code, pmi.protocol;
print pmv.data[0], pmv.header.code, pmv.protocol;
};
};
'>

Result
This example shows that any changes in value to lists and structs contained in the copied struct instance
(pmv) are not propagated to the original struct instance (pmi) because the struct has been recursively
duplicated.
cmd-prompt> sys.m()
pmi.data[0] = 0x1b
pmi.header.code = 0x43dfc545
pmi.protocol = ATM
pmv.data[0] = 0xff
pmv.header.code = 0xaa
pmv.protocol = IEEE

Specman e Language Reference


1999-2015

1460

Product Version 15.1


All Rights Reserved.

See Also

The copy() Method of any_struct or any_unit on page 1178

deep_compare() on page 1461

deep_compare_physical() on page 1466

attribute field on page 248

trace deep in the Specman Command Reference

27.2.2

deep_compare()

Purpose
Perform a recursive comparison of two struct instances

Category
Predefined routine

Syntax
deep_compare(struct-inst1: exp, struct-inst2: exp, max-diffs: int): list of string
Syntax Example
var diff: list of string = deep_compare(pmi[0], pmi[1], 100);

Parameters
struct-inst1,
struct-inst2

An expression returning a struct instance.

max-diffs

A positive integer (or UNDEF for unlimited) representing the maximum number
of differences you want reported.

Description
Returns a list of strings, where each string describes a single difference between the two struct instances.
This routine descends recursively through the fields of a struct and its descendants, comparing each field
or ignoring it, depending on the deep_compare attribute set for that field.
The two struct instances are deep equal if the returned list is empty.
Specman e Language Reference
1999-2015

1461
.

Product Version 15.1


All Rights Reserved.

Deep equal is defined as follows:

Two struct instances are deep equal if they are of the same type and all their fields are deep equal.

Two scalar fields are deep equal if an equality operation applied to them is TRUE.

Two list instances are deep equal if they are of the same size and all their items are deep equal.

Topology is taken into account. If two non-scalar instances are not in the same location in the deep
compare graphs, they are not equal. A deep compare graph is the imaginary directed graph created by
traversing the structs and lists compared, where its nodes are the structs or lists, and its edges are deep
references to other structs or lists.

Type Equality for when Subtypes for deep_compare() and


deep_compare_physical()
Note the following:

If two when subtypes have exactly the same set of fields, they are considered to be the same type for
the deep_compare() routine.
If two when subtypes have exactly the same set of physical fields, they are considered to be same
type for the deep_compare_physical() routine, even if their sets of non-physical fields are different.

The Differences Reported by deep_compare()


The following table details the differences that are reported in the strings returned by deep_compare().
The differences depend on the type of the field and the deep_compare attribute (normal, reference,
ignore) set for that field. For an example of how field attributes affect deep_compare(), see attribute
field on page 248.)
Field Type/
Attribute

Normal

Reference

Ignore

scalar

Their values, if different, are


reported.

Their values, if
different, are reported.

The fields are not


compared.

string

Their values, if different, are


reported.

Their values, if
different, are reported.

The fields are not


compared.

scalar list

Their sizes, if different, are


reported. All items in the
smaller list are compared to
those in the longer list and
their differences are reported.

The fields are equal if


their addresses are the
same. The items are not
compared.

The fields are not


compared.

Specman e Language Reference


1999-2015

1462

Product Version 15.1


All Rights Reserved.

Field Type/
Attribute
struct

Normal

Reference

Ignore

If two structs are not of the


same type, their type
difference is reported. Also,
any differences in common
fields is reported. 1

The fields are equal if


they point to the same
struct instance. 2

The fields are not


compared and no
differences for them
or their descendants
are reported.

If two structs are of the same


type, every field difference is
reported.
list of structs

Their sizes, if different, are


reported. All structs in the
smaller list are deep compared
to those in the longer list and
their differences are reported.

If the fields do not point


to the same instance,
only the addresses are
reported as different;
the data is not
compared.
The fields are equal if
their addresses are the
same and they point to
the same struct
instance. 2

The fields are not


compared and no
differences for them
or their descendants
are reported.

1. Two fields are considered common only if the two structs are the same type, if they are
both subtypes of the same base type, or if one is a base type of the other.
2. If the reference points inside the deep compare graph, a limited topological equivalence
check is performed, not just an address comparison.

Difference String Format


The difference string is in the following format:
Differences between <inst1-id> and <inst2-id>
--------------------------------------------<path>:
<inst1-value>
!=
<inst2-value>

Specman e Language Reference


1999-2015

1463
.

Product Version 15.1


All Rights Reserved.

path

A list of field names separated by periods (.) from (and not including) the struct
instances being compared to the field with the difference.

value

For scalar field differences, value is the result of out(field).


For struct field type differences, value is the name of the subtype for the instance.
For list field size differences, size() is appended to the path and value is the result of
out(field.size()).
For a shallow comparison of struct fields that point outside the deep compare graph,
value is the struct address.
For a comparison of struct fields that point to different locations in the deep compare
graphs (topological difference), value is struct# appended to an index representing its
location in the deep compare graph.

Note
The same two struct instances or the same two list instances are not compared more than once during a
single call to deep_compare().

Example
This example uses deep_compare() to show the differences between copying nested structs by
reference (with copy()) and copying nested structs by allocation (with deep_copy()).
<'
struct a {
x: byte;
};
struct b {
as: list of a;
keep as.size() in [2 .. 3];
};
struct c {
bs: list of b;
keep bs.size() in [2 .. 3];
print() is {
var idx: uint;
for each b (b) in bs {
idx = index;
for each a (a) in b.as {
out ("b[",idx,"] - a[",index,"] : ",
hex(bs[idx].as[index].x));
};
Specman e Language Reference
1999-2015

1464

Product Version 15.1


All Rights Reserved.

};
};
};
extend sys {
c1: c;
post_generate() is also {
var c2: c = new;
var c3: c = new;
out("C1:");
c1.print();
// copy by allocation
out("C2:");
c2 = deep_copy(c1);
c2.print();
print deep_compare(c1,c2,20);
// copy by reference
out("C3:");
c3 = c1.copy();
c3.print();
print deep_compare(c1,c3,20);
// demonstrate difference - change original
out("Change C1:");
c1.bs[0].as[0].x = 0;
c1.print();
print deep_compare(c1,c2,20);
print deep_compare(c1,c3,20);
};
};
'>

Result
The results show the differences between the two ways of copying. The c2 instance is copied by
deep_copy(), so when the value of x is changed in the original instance, c1, the value of x in c2 is not
changed. In contrast, the value of x in c3 is changed because c3 was copied by reference. Note that
deep_compare() = empty means that the two struct instances are deep equal.
Specman deep5> gen
Doing setup ...
Specman e Language Reference
1999-2015

1465
.

Product Version 15.1


All Rights Reserved.

Generating the test using seed 0x1...


C1:
b[0x0] - a[0x0] : 0x75
b[0x0] - a[0x1] : 0x8a
b[0x1] - a[0x0] : 0x0a
b[0x1] - a[0x1] : 0x2a
C2:
b[0x0] - a[0x0] : 0x75
b[0x0] - a[0x1] : 0x8a
b[0x1] - a[0x0] : 0x0a
b[0x1] - a[0x1] : 0x2a
deep_compare(c1,c2,20) = (empty)
C3:
b[0x0] - a[0x0] : 0x75
b[0x0] - a[0x1] : 0x8a
b[0x1] - a[0x0] : 0x0a
b[0x1] - a[0x1] : 0x2a
deep_compare(c1,c3,20) = (empty)
Change C1:
b[0x0] - a[0x0] : 0x00
b[0x0] - a[0x1] : 0x8a
b[0x1] - a[0x0] : 0x0a
b[0x1] - a[0x1] : 0x2a
deep_compare(c1,c2,20) =
0.
"Differences between c-@0 and c-@1
--------------------------------------------------"
1.
"bs[0x0].as[0x0].x:
0x00
!=
0x75"
deep_compare(c1,c3,20) = (empty)

See Also

deep_compare_physical() on page 1466

deep_copy() on page 1458

attribute field on page 248

trace deep in the Specman Command Reference

27.2.3

deep_compare_physical()

Purpose
Perform a recursive comparison of the physical fields of two struct instances

Specman e Language Reference


1999-2015

1466

Product Version 15.1


All Rights Reserved.

Category
Predefined routine

Syntax
deep_compare_physical(struct-inst1: exp, struct-inst2: exp, max-diffs: int): list of string
Syntax Example
var diff: list of string = deep_compare_physical(pmi[0],
pmi[1], 100);

Parameters
struct-inst1,
struct-inst2

An expression returning a struct instance.

max-diffs

An integer representing the maximum number of differences you want reported.

Description
Returns a list of strings, where each string describes a single difference between the two struct instances.
This routine descends recursively through the fields of a struct and its descendants, ignoring all
non-physical fields and comparing each physical field or ignoring it, depending on the
deep_compare_physical attribute set for that field.
This routine is the same as the deep_compare() routine except that only physical fields (indicated with
the % operator prefixed to the field name) are compared.
The two struct instances are deep equal if the returned list is empty.
Deep equal is defined as follows:

Two struct instances are deep equal if they are of the same type and all their fields are deep equal.

Two scalar fields are deep equal if an equality operation applied to them is TRUE.

Two list instances are deep equal if they are of the same size and all their items are deep equal.

Type Equality for when Subtypes


Note the following:

If two when subtypes have exactly the same set of fields, they are considered to be the same type for
the deep_compare() routine.

Specman e Language Reference


1999-2015

1467
.

Product Version 15.1


All Rights Reserved.

If two when subtypes have exactly the same set of physical fields, they are considered to be same
type for the deep_compare_physical() routine, even if their sets of non-physical fields are different.

Example
<'
struct packet {
%header: header;
%data[10] :list of byte;
protocol: [ATM, ETH, IEEE];
};
struct header {
%code: uint;
};
extend sys {
pmi[2]: list of packet;
post_generate() is also {
var diff: list of string = deep_compare_physical(pmi[0],
pmi[1], 100);
if (diff.size() != 0) {
out(diff);
};
};
};
'>

Result
This example shows the differences between the physical fields of the packet instances. The differences
between the protocol fields are not reported.
Differences between packet-@0 and packet-@1
-------------------------------------------------header.code:
1138738501
!=
3071222567
data[0]:
27
!=
37
data[1]:
132
!=
56
data[2]:
163
!=
69
data[3]:
71
!=
236
data[4]:
178
!=
120
data[5]:
230
!=
100
data[6]:
116
!=
239
data[7]:
241
!=
216
data[8]:
238
!=
144
data[9]:
150
!=
253

Specman e Language Reference


1999-2015

1468

Product Version 15.1


All Rights Reserved.

See Also

deep_compare() on page 1461

deep_copy() on page 1458

attribute field on page 248

trace deep in the Specman Command Reference

27.3 Arithmetic Routines


The following sections describe the predefined arithmetic routines in e:

min() on page 1469

max() on page 1471

abs() on page 1472

odd() on page 1473

even() on page 1474

ilog2() on page 1475

ilog10() on page 1476

ipow() on page 1477

isqrt() on page 1478

div_round_up() on page 1480

See Also

Arithmetic Routines Supporting Real Type on page 1482

27.3.1

min()

Purpose
Get the minimum of two numeric values

Category
Pseudo method

Specman e Language Reference


1999-2015

1469
.

Product Version 15.1


All Rights Reserved.

Syntax
min(x: numeric-type, y: numeric-type): numeric-type
Syntax Example
print min((x + 5), y);

Parameters
x

A numeric expression.

A numeric expression.

Description
Returns the smaller of the two numeric values.

Example
<'
extend sys {
m1() is {
var x:int = 5;
var y: int = 123;
print min((x + 5), y);
};
};
'>

Result
Specman > sys.m1()
min((x + 5), y) = 10

See Also

Arithmetic Routines on page 1469

Specman e Language Reference


1999-2015

1470

Product Version 15.1


All Rights Reserved.

27.3.2

max()

Purpose
Get the maximum of two numeric values

Category
Pseudo method

Syntax
max(x: numeric-type, y: numeric-type): numeric-type
Syntax Example
print max((x + 5), y);

Parameters
x

A numeric expression.

A numeric expression.

Description
Returns the larger of the two numeric values.

Example
<'
extend sys {
m1() is {
var x:int = 5;
var y: int = 123;
print max((x + 5), y);
};
};
'>

Result
Specman > sys.m1()
Specman e Language Reference
1999-2015

1471
.

Product Version 15.1


All Rights Reserved.

max((x + 5), y) = 123

See Also

Arithmetic Routines on page 1469

27.3.3

abs()

Purpose
Get the absolute value

Category
Routine

Syntax
abs(x: numeric-type): numeric-type
Syntax Example
print abs(x);

Parameter
x

A numeric expression.

Description
Returns the absolute value of the expression.

Example
<'
extend sys {
m1() is {
var x: int = -5;
print abs(x);
};
};
'>
Specman e Language Reference
1999-2015

1472

Product Version 15.1


All Rights Reserved.

Result
Specman > sys.m1()
abs(x) = 5

See Also

Arithmetic Routines on page 1469

27.3.4

odd()

Purpose
Check if an integer is odd

Category
Routine

Syntax
odd(x: int): bool
Syntax Example
print odd(x);

Parameter
x

An integer expression.

Description
Returns TRUE if the integer is odd, FALSE if the integer is even.
Note

You cannot use this routine on real types.

Example
<'
extend sys {
m1() is {
var x: int = -5;
Specman e Language Reference
1999-2015

1473
.

Product Version 15.1


All Rights Reserved.

print odd(x);
};
};
'>

Result
Specman > sys.m1()
odd(x) = TRUE

See Also

Arithmetic Routines on page 1469

27.3.5

even()

Purpose
Check if an integer is even

Category
Routine

Syntax
even(x: int): bool
Syntax Example
print even(x);

Parameter
x

An integer expression.

Description
Returns TRUE if the integer passed to it is even, FALSE if the integer is odd.
Note

You cannot use this routine on real types.

Specman e Language Reference


1999-2015

1474

Product Version 15.1


All Rights Reserved.

Example
<'
extend sys {
m1() is {
var x: int = -5;
print even(x);
};
};
'>

Result
Specman > sys.m1()
even(x) = FALSE

See Also

Arithmetic Routines on page 1469

27.3.6

ilog2()

Purpose
Get the base-2 logarithm

Category
Routine

Syntax
ilog2(x: uint): int
Syntax Example
print ilog2(x);

Parameter
x

An unsigned integer expression.

Specman e Language Reference


1999-2015

1475
.

Product Version 15.1


All Rights Reserved.

Description
Returns the integer part of the base-2 logarithm of x.

Example
<'
extend sys {
m1() is {
var x: int = 1034;
print ilog2(x);
};
};
'>

Result
Specman > sys.m1()
ilog2(x) = 10

See Also

Arithmetic Routines on page 1469

27.3.7

ilog10()

Purpose
Get the base-10 logarithm

Category
Routine

Syntax
ilog10(x: uint): int
Syntax Example
print ilog10(x);

Specman e Language Reference


1999-2015

1476

Product Version 15.1


All Rights Reserved.

Parameter
x

An unsigned integer expression.

Description
Returns the integer part of the base-10 logarithm of x.

Example
<'
extend sys {
m1() is {
var x: int = 1034;
print ilog10(x);
};
};
'>

Result
Specman > sys.m1()
ilog10(x) = 3

See Also

Arithmetic Routines on page 1469

27.3.8

ipow()

Purpose
Raise to a power

Category
Routine

Syntax
ipow(x: int, y: int): int

Specman e Language Reference


1999-2015

1477
.

Product Version 15.1


All Rights Reserved.

Syntax Example
print ipow(x, y);

Parameters
x

An integer expression.

An integer expression.

Description
Raises x to the power of y and returns the integer result.

Example
<'
extend sys {
m1() is {
var x: int = 4;
var y: int = 3;
print ipow(x, y);
};
};
'>

Result
Specman > sys.m1()
ipow(x, y) = 64

See Also

Arithmetic Routines on page 1469

27.3.9

isqrt()

Purpose
Get the square root

Specman e Language Reference


1999-2015

1478

Product Version 15.1


All Rights Reserved.

Category
Routine

Syntax
isqrt(x: uint): int
Syntax Example
print isqrt(x);

Parameter
x

An unsigned integer expression.

Description
Returns the integer part of the square root of x.

Example
<'
extend sys {
m1() is {
var x: int = 67;
print isqrt(x);
};
};
'>

Result
Specman > sys.m1()
isqrt(x) = 8

See Also

Arithmetic Routines on page 1469

Specman e Language Reference


1999-2015

1479
.

Product Version 15.1


All Rights Reserved.

27.3.10 div_round_up()
Purpose
Division rounded up

Category
Routine

Syntax
div_round_up(x: int, y: int): int
Syntax Example
print div_round_up(x, y);

Parameters
x

An integer expression. to use as the dividend.

An integer expression to use as the divisor.

Description
Returns the result of x / y rounded up to the next integer.

Example
<'
extend sys {
m1() is {
var x: int = 5;
var y: int = 2;
print div_round_up(x, y);
};
};
'>

Result
Specman > sys.m1()
Specman e Language Reference
1999-2015

1480

Product Version 15.1


All Rights Reserved.

div_round_up(x, y) = 3

See Also

Arithmetic Routines on page 1469

/ arithmetic operator in + - * / % on page 85

27.4 Routines for Random Distribution of Numbers


Specman supports the following routines to generate random numbers:
Table 27-1
Routine

Routines that Generate Random Numbers


Description

dist_uniform(from, to): int


Returns a random integer that is in the range specified by from to to, using a uniform
distribution.
All parameter values and the return value for this routine are integers of any bit size:

from is the lowest value of the range.


to is the highest value of the range.

dist_normal(from, to, mean, standard-deviation): int


Returns a random integer that is in the range specified by from to to, using a normal
distribution.
All parameter values and the return value for this routine are integers of any bit size:

from is the lowest value of the range.


to is the highest value of the range.
mean (also known as the expectation) is the location of the peak.
standard-deviation identifies how much variation exists from the peak.

rdist_uniform(from, to): real


Returns a random real number that is in the range specified by from to to, using a
uniform distribution.
All parameters for this method are real numbers:

from is the lowest value of the range.


to is the highest value of the range.

Specman e Language Reference


1999-2015

1481
.

Product Version 15.1


All Rights Reserved.

Table 27-1

Routines that Generate Random Numbers

Routine

Description

rdist_normal(from to, mean, standard-deviation): real


Returns a random real number that is in the range specified by from to to, using a
normal distribution.
All parameters for this method are real numbers:

from is the lowest value of the range.


to is the highest value of the range.
mean (also known as the expectation) is the location of the peak.
standard-deviation identifies how much variation exists from the peak.

See Also

soft... select on page 637

The real Type on page 158

27.5 Routines Supporting the real Type


The following types of routines are supported for the real type:

Arithmetic Routines Supporting Real Type on page 1482

See Also

rdist_uniform() and rdist_normal() in Routines for Random Distribution of Numbers on page 1481

27.5.1

Arithmetic Routines Supporting Real Type

The following arithmetic routines support real type objects:


Table 27-2

Arithmetic Routines Supporting real Types

Routine

Description

floor(real): real

Returns the largest integer that is less than or equal to the parameter.

ceil(real): real

Returns the smallest integer that is greater than or equal to the parameter.

Specman e Language Reference


1999-2015

1482

Product Version 15.1


All Rights Reserved.

Table 27-2

Arithmetic Routines Supporting real Types

Routine

Description

round(real): real

Returns the closest integer to the parameter. In the case of a tie then it
returns the integer with the higher absolute value.

log(real): real

Returns the natural logarithm of the parameter.

log10(real): real

Returns the base-10 logarithm of parameter.

pow(real, real): real

Returns the value of the first parameter raised to the power of second one.

sqrt(real): real

Returns the square root of the parameter.

exp(real): real

Returns the value of e raised to the power of the parameter.

sin(real): real

Returns the sine of the parameter given in radians.

cos(real): real

Returns the cosine of the parameter given in radians.

tan(real): real

Returns the tangent of the parameter given in radians.

asin(real): real

Returns the arc sine of the parameter.

acos(real): real

Returns the arc cosine of the parameter.

atan(real): real

Returns the arc tangent of the parameter.

sinh(real): real

Returns the hyperbolic sine of the parameter.

cosh(real): real

Returns the hyperbolic cosine of the parameter.

tanh(real): real

Returns the hyperbolic tangent of the parameter.

asinh(real): real

Returns the inverse hyperbolic sine of the parameter.

acosh(real): real

Returns the inverse hyperbolic cosine of the parameter.

atanh(real): real

Returns the inverse hyperbolic tangent of the parameter.

atan2(real, real): real

Returns the arc tangent of the two parameters.

hypot(real, real): real

Returns the distance of the point defined by the two parameters from the
origin.

is_nan(real): bool

Returns TRUE if the parameters value is Not-a-Number (NaN).

is_finite(real): bool

Returns TRUE if the parameters value is a finite real value that is, it is not
infinity, negative infinity, or NaN).

Specman e Language Reference


1999-2015

1483
.

Product Version 15.1


All Rights Reserved.

Note For integer routines like ilog(), ilog10(), ilog2(), ipow(), and isqrt(), whose return type is based
on the expected type, if the expected type is real, then the return type is int (bits:*).

See Also

The real Type on page 158

27.6 Bitwise Routines


The predefined bitwise routines perform Boolean operations bit-by-bit and return a single-bit result.

27.6.1

bitwise_op()

Purpose
Perform a Verilog-style unary reduction operation

Category
Pseudo-method

Syntax
bitwise_op(exp: int|uint): bit
Syntax Example
print bitwise_and(b);

Parameters
op

One of and, or, xor, nand, nor, xnor.

exp

A 32-bit numeric expression.

Description
Performs a Verilog-style unary reduction operation on a single operand to produce a single bit result.
There is no reduction operator in e, but the bitwise_op() routines perform the same functions as
reduction operators in Verilog. For example, you can use bitwise_xor() to calculate parity.

Specman e Language Reference


1999-2015

1484

Product Version 15.1


All Rights Reserved.

For bitwise_nand(), bitwise_nor(), and bitwise_xnor(), the result is computed by inverting the result
of the bitwise_and(), bitwise_or(), and bitwise_xor() operation, respectively.
Table 27-3 shows the predefined pseudo-methods for bitwise operations.

Table 27-3

Bitwise Operation Pseudo-Methods

Pseudo-Method

Operation

bitwise_and()

Boolean AND of all bits

bitwise_or()

Boolean OR of all bits

bitwise_xor()

Boolean XOR of all bits

bitwise_nand()

!bitwise_and()

bitwise_nor()

!bitwise_or()

bitwise_xnor()

!bitwise_xor()

Note
These routines cannot be used to perform bitwise operations on:

Unbounded integers

real data types

Example 1
<'
struct nums {
m1() is {
var b: uint = 0xffffffff;
print bitwise_and(b);
print bitwise_nand(b);
};
};
extend sys {
pmi:nums;
};
'>

Result
cmd-prompt> sys.pmi.m()
Specman e Language Reference
1999-2015

1485
.

Product Version 15.1


All Rights Reserved.

bitwise_and(b) = 1
bitwise_nand(b) = 0

Example 2
<'
struct nums {
m1() is {
var b: uint = 0xcccccccc;
print bitwise_or(b);
print bitwise_nor(b);
};
};
extend sys {
pmi:nums;
};
'>

Result
cmd-prompt> sys.pmi.m()
bitwise_or(b) = 1
bitwise_nor(b) = 0

Example 3
<'
struct nums {
m1() is {
var b: uint = 0x1;
print bitwise_xor(b);
print bitwise_xnor(b);
};
};
extend sys {
pmi:nums;
};
'>

Result
cmd-prompt> sys.pmi.m()
bitwise_xor(b) = 1
bitwise_xnor(b) = 0

Specman e Language Reference


1999-2015

1486

Product Version 15.1


All Rights Reserved.

See Also

Arithmetic Routines on page 1469

27.7 String Routines


None of the string routines in e modify the input parameters. When you pass a parameter to one of these
routines, the routine makes a copy of the parameter, manipulates the copy, and returns the copy.
You can use the as_a() casting operator to convert strings to integers or bytes. See Table 2-7, Type
Conversion Between Strings and Scalars or Lists of Scalars.
Note

To copy a string, use The copy() Method of any_struct or any_unit on page 1178.

Routines that convert expressions into a string:

append() on page 1488

appendf() on page 1490

quote() on page 1496

to_string() on page 1518

Routines that manipulate substrings:

str_join() on page 1502

str_split() on page 1512

str_split_all() on page 1514

str_sub() on page 1515

Routines that manipulate regular expressions:

str_match() on page 1505

str_replace() on page 1509

str_insensitive() on page 1501

Routines that change the radix of a numeric expression:

bin() on page 1492

dec() on page 1493

hex() on page 1494

Routines that manipulate the length of an expression:

str_chop() on page 1497

str_empty() on page 1498

Specman e Language Reference


1999-2015

1487
.

Product Version 15.1


All Rights Reserved.

str_exactly() on page 1499

str_len() on page 1503

str_pad() on page 1508

Routines that are useful within Specman macros:

quote() on page 1496

str_insensitive() on page 1501

str_expand_dots() on page 1522

reject_match() on page 1523

Routines that manipulate the case of characters within a string:

str_lower() on page 1504

str_upper() on page 1517

str_insensitive() on page 1501

See Also

String Matching on page 99

The string Type on page 158

Table 2-7 on page 205

File Routines on page 1555

27.7.1

append()

Purpose
Concatenate expressions into a string

Category
Routine

Syntax
append(): string
append(item: exp, ...): string

Specman e Language Reference


1999-2015

1488

Product Version 15.1


All Rights Reserved.

Syntax Example
message = append(list1, " ", list2);

Parameter
item

A legal e expression. String expressions must be enclosed in double quotes. If the


expression is a struct instance, the struct ID is printed. If no items are passed to
append(), it returns an empty string.

Description
Calls to_string() on page 1518 to convert each expression to a string using the current radix setting for
any numeric expressions, then concatenates them and returns the result as a single string.

Note
If you are concatenating a very large number of strings (for example, a long list of strings) into a single
string, it is better to use str_join(), for performance reasons. If there are 10000 items in my_list, the for
loop shown below makes 10000 copies of the lengthening string, hence creating an n**2 effect:
foo = "";
for each in l {
foo = append(foo, it);
};

In contrast, the following will create a string of the right length and do a single copy operation:
foo = str_join(l, "");

Example
extend sys {
m1() is {
var message: string;
var u1:uint = 55;
var u2:uint = 44;
message = append(u1, " ", u2);
print message;
var list1:list of bit = {0;1;0;1};
var list2:list of bit = {1;1;1;0};
message = append(list1, " ", list2);
print message;
};
};

Specman e Language Reference


1999-2015

1489
.

Product Version 15.1


All Rights Reserved.

Result
The radix setting for this example was hex.
Specman > sys.m1()
message = "0x37 0x2c"
message = "0x0 0x1 0x0 0x1 0x1 0x1 0x1 0x0"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.2

appendf()

Purpose
Concatenate expressions into a string according to a given format

Category
Routine

Syntax
appendf(format: string, item: exp, ...): string
Syntax Example
message = appendf("%4d\n %4d\n %4d\n", 255, 54, 1570);

Parameters
format

A string expression containing a standard C formatting mask for each item. See
Format String on page 1528 for more information.

item

A legal e expression. String expressions must be enclosed in double quotes. If the


expression is a struct instance, the struct ID is printed.

Specman e Language Reference


1999-2015

1490

Product Version 15.1


All Rights Reserved.

Description
Converts each expression to a string using the current radix setting for any numeric expressions and the
specified format, then concatenates them and returns the result as a single string.
Notes

If the number and type of masks in the format string does not match the number and type of
expressions, an error is issued.
The Specman implementation of appendf() calls the sprintf function in the standard C library.
Because the implementation of sprintf might vary between platforms, the behavior of appendf()
might also vary from what is described here, depending on the platform.

Example
<'
extend sys {
m1() is {
var message: string;
message = appendf("%4d\n %4d\n %4d\n", 255, 54, 1570);
out(message);
};
};
'>

Result
The radix setting for this example was DEC.
Specman > sys.m1()
255
54
1570

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

Specman e Language Reference


1999-2015

1491
.

Product Version 15.1


All Rights Reserved.

27.7.3

bin()

Purpose
Concatenate expressions into string, using binary representation for numeric types

Category
Routine

Syntax
bin(item: exp, ...): string
Syntax Example
var my_string: string = bin(pi.i, " ", list1, " ",8);

Parameter
item

A legal e expression. String expressions must be enclosed in double quotes. If the


expression is a struct instance, the struct ID is printed.

Description
Concatenates one or more expressions into a string, using binary representation for any expressions of
numeric types, regardless of the current radix setting.

Example
<'
struct p {
i:int;
};
extend sys {
pi:p;
m1() is {
pi = new;
pi.i = 11;
var list1:list of bit = {0;1;1;0};
var my_string: string = bin(pi.i, " ", list1, " ",8);
print my_string;
Specman e Language Reference
1999-2015

1492

Product Version 15.1


All Rights Reserved.

};
};
'>

Result
Specman > sys.m1()
my_string = "0b1011 0b0 0b1 0b1 0b0 0b1000"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.4

dec()

Purpose
Concatenate expressions into string, using decimal representation for numeric types

Category
Routine

Syntax
dec(item: exp, ...): string
Syntax Example
var my_string: string = dec(pi.i, " ", list1, " ",8);

Parameter
item

A legal e expression. String expressions must be enclosed in double quotes. If the


expression is a struct instance, the struct ID is printed.

Description
Concatenates one or more expressions into a string, using decimal representation for any expressions of
numeric types, regardless of the current radix setting.

Specman e Language Reference


1999-2015

1493
.

Product Version 15.1


All Rights Reserved.

Example
<'
struct p {
i:int;
};
extend sys {
pi:p;
m1() is {
pi = new;
pi.i = 11;
var list1:list of bit = {0;1;1;0};
var my_string: string = dec(pi.i, " ", list1, " ",8);
print my_string;
};
};
'>

Result
Specman > sys.m1()
my_string = "11 0 1 1 0 8"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.5

hex()

Purpose
Concatenate expressions into string, using hexadecimal representation for numeric types

Category
Routine

Syntax
hex(item: exp, ...): string

Specman e Language Reference


1999-2015

1494

Product Version 15.1


All Rights Reserved.

Syntax Example
var my_string: string = hex(pi.i, " ", list1, " ",8);

Parameter
item

A list of one or more legal e expressions. String expressions must be enclosed in


double quotes. If the expression is a struct instance, the struct ID is printed.

Description
Concatenates one or more expressions into a string, using hexadecimal representation for any
expressions of numeric types, regardless of the current radix setting.

Example
<'
struct p {
i: int;
};
extend sys {
pi: p;
m1() is {
pi = new;
pi.i = 11;
var list1:list of bit = {0;1;1;0};
var my_string: string = hex(pi.i, " ", list1, " ",8);
print my_string;
};
};
'>

Result
Specman > sys.m1()
my_string = "0xb 0x0 0x1 0x1 0x0 0x8"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

Specman e Language Reference


1999-2015

1495
.

Product Version 15.1


All Rights Reserved.

27.7.6

quote()

Purpose
Enclose a string within double quotes

Category
Routine

Syntax
quote(text: string): string
Syntax Example
out(quote(message));

Parameter
text

An expression of type string.

Description
Returns a copy of the text, enclosed in double quotes (" "), with any internal quote or backslash preceded
by a backslash (\).
This routine is useful when creating commands with define.

Example
<'
extend sys {
m1() is {
var message: string = "Error occurred in \"D\" block...";
out(message);
out(quote(message));
};
};
'>

Specman e Language Reference


1999-2015

1496

Product Version 15.1


All Rights Reserved.

Result
Specman > sys.m1()
Error occurred in "D" block...
"Error occurred in \"D\" block..."

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.7

str_chop()

Purpose
Chop the tail of a string

Category
Routine

Syntax
str_chop(str: string, length: int): string
Syntax Example
var test_dir: string = str_chop(tmp_dir, 13);

Parameters
str

An expression of type string.

length

An integer representing the desired length.

Description
Returns str (if its length is <= length), or a copy of the first length chars of str.
Removes characters from the end of a string, returning a string of the desired length. If the original string
is already less than or equal to the desired length, this routine returns a copy of the original string.

Specman e Language Reference


1999-2015

1497
.

Product Version 15.1


All Rights Reserved.

Example
<'
extend sys {
m1() is {
var tmp_dir: string = "/rtests/test1/tmp";
var test_dir: string = str_chop(tmp_dir, 13);
print test_dir;
};
};
'>

Result
Specman > sys.m1()
test_dir = "/rtests/test1"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.8

str_empty()

Purpose
Check if a string is empty

Category
Routine

Syntax
str_empty(str: string): bool
Syntax Example
print str_empty(s1);

Specman e Language Reference


1999-2015

1498

Product Version 15.1


All Rights Reserved.

Parameter
str

An expression of type string.

Description
Returns TRUE if the string is uninitialized or empty.

Example
<'
extend sys{
m1() is {
var s1: string;
var s2: string = "";
print str_empty(s1);
print str_empty(s2);
};
};
'>

Result
Specman > sys.m1()
str_empty(s1) = TRUE
str_empty(s2) = TRUE

See Also

String Routines on page 1487

27.7.9

str_exactly()

Purpose
Get a string with exact length

Category
Routine

Specman e Language Reference


1999-2015

1499
.

Product Version 15.1


All Rights Reserved.

Syntax
str_exactly(str: string, length: int): string
Syntax Example
var long: string = str_exactly("123", 6);

Parameters
str

An expression of type string.

length

An integer representing the desired length.

Description
Returns a copy of the original string, whose length is the desired length, by adding blanks to the right or
by truncating the expression from the right as necessary. If non-blank characters are truncated, the *
character appears as the last character in the string returned.

Example
<'
extend sys {
m1() is {
var short: string = str_exactly("123000",3);
print short;
var long: string = str_exactly("123", 6);
print long;
};
};
'>

Result
Specman > sys.m1()
short = "12*"
long = "123
"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

Specman e Language Reference


1999-2015

1500

Product Version 15.1


All Rights Reserved.

27.7.10 str_insensitive()
Purpose
Get a case-insensitive AWK-style regular-expression

Category
Routine

Syntax
str_insensitive(regular_exp: string): string
Syntax Example
var insensitive: string = str_insensitive("/hello.*/");

Parameter
regular-exp

An AWK-style regular expression.

Description
Returns an AWK-style regular expression string which is the case-insensitive version of the original
regular expression.

Example
<'
extend sys {
m1() is {
var insensitive: string = str_insensitive("/hello.*/");
print insensitive;
};
};
'>

Result
Specman > sys.m1()
insensitive = "/[Hh][Ee][Ll][Ll][Oo].*/"

Specman e Language Reference


1999-2015

1501
.

Product Version 15.1


All Rights Reserved.

See Also

AWK-Style String Matching on page 101

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.11 str_join()
Purpose
Concatenate a list of strings

Category
Routine

Syntax
str_join(list: list of string, separator: string): string
Syntax Example
var s := str_join(slist," - ");

Parameters
list

A list of type string.

separator

The string that will be used to separate the list elements.

Description
Returns a single string which is the concatenation of the strings in the list of strings, separated by the
separator.

Example
<'
extend sys {
m1() is {
var slist: list of string = {"first";"second";"third"};
var s := str_join(slist," - ");
Specman e Language Reference
1999-2015

1502

Product Version 15.1


All Rights Reserved.

print s;
};
};
'>

Result
Specman > sys.m1()
s = "first - second - third"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.12 str_len()
Purpose
Get string length

Category
Routine

Syntax
str_len(str: string): int
Syntax Example
var length: int = str_len("hello");

Parameter
str

An expression of type string.

Description
Returns the number of characters in the original string, not counting the terminating NULL character \0.

Specman e Language Reference


1999-2015

1503
.

Product Version 15.1


All Rights Reserved.

Example
<'
extend sys {
m1() is {
var length: int = str_len("hello");
print length;
};
};
'>

Result
Specman > sys.m1()
length = 5

See Also

String Routines on page 1487

27.7.13 str_lower()
Purpose
Convert string to lowercase

Category
Routine

Syntax
str_lower(str: string): string
Syntax Example
var lower: string = str_lower("UPPER");

Parameter
str

An expression of type string.

Specman e Language Reference


1999-2015

1504

Product Version 15.1


All Rights Reserved.

Description
Converts all upper case characters in the original string to lower case and returns the string.

Example
<'
extend sys {
m1() is {
var lower: string = str_lower("UPPER");
print lower;
};
};
'>

Result
Specman > sys.m1()
lower = "upper"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.14 str_match()
Purpose
Match strings

Category
Routine

Syntax
str_match(str: string, regular-exp: string): bool
Syntax Example
print str_match("ace", "/c(e)?$/");

Specman e Language Reference


1999-2015

1505
.

Product Version 15.1


All Rights Reserved.

Parameters
str

An expression of type string.

regular-exp

An AWK-style or native Specman regular expression. If not surrounded by


slashes, the expression is treated as a native style expression. See String
Matching on page 99 for more information on these types of expressions.

Description
Returns TRUE if the strings match, or FALSE if the strings do not match. The routine str_match() is
fully equivalent to the operator ~.
After a successful match, you can use the local pseudo-variable $0 to retrieve the entire matched string.
The variables $1, $2...$30 hold portions of the matched string (the submatches), either:

The portions of a native Specman regular expression that correspond to the asterisk or ellipsis
characters present in the match pattern.
The portions of an AWK-style regular expression that correspond to characters enclosed in
parentheses in the match pattern.

Example 1
This example uses AWK-style regular expressions. See AWK-Style String Matching on page 101 for
more information on these types of expressions.
<'
extend sys {
m1() is {
print str_match("a", "/^(a)?(b)?$/"); -- matches "ab", "a", or "b"
print $0, $1, $2;
print str_match("hello","/^\\d*$/"); -- matches string with 0
-- or more digits
print $0, $1, $2;
print str_match("ab", "/^(a)?(b)?$/");
print $0, $1, $2;
print str_match("ace", "/c(e)?$/"); -- matches string ending
-- in "c" or "ce"
print $0, $1;
};
};
'>

Specman e Language Reference


1999-2015

1506

Product Version 15.1


All Rights Reserved.

Result
Specman > sys.m1()
str_match("a", "/^(a)?(b)?$/") = TRUE
$0 = "a"
-- stores the entire matched portion of the string
$1 = "a"
-- stores the first match
$2 = ""
str_match("hello","/^\\d*$/") = FALSE
$0 = "a"
-- the values from the previous call to str_match() persist
$1 = "a"
$2 = ""
str_match("ab", "/^(a)?(b)?$/") = TRUE
$0 = "ab"
$1 = "a"
$2 = "b"
str_match("ace", "/c(e)?$/") = TRUE
$0 = "ce"
$1 = "e"

Example 2
This example uses native Specman regular expressions. See Native Specman String Matching on page
99 for more information on these types of expressions. The * character matches any sequence of
non-white characters, while the "..." string matches any sequence of characters, including white space.
<'
extend sys {
m1() is {
var s:string = "a bc";
print str_match(s, "a*");
print $0, $1, $2;
print str_match(s, "* *");
print $0, $1, $2;
print str_match(s, "a...");
print $0, $1, $2;
};
};
'>

Result
Specman > sys.m1()
str_match(s, "a*") = FALSE
$0 = ""
$1 = ""
$2 = ""
str_match(s, "* *") = TRUE
Specman e Language Reference
1999-2015

1507
.

Product Version 15.1


All Rights Reserved.

$0 = "a bc"
$1 = "a"
$2 = "bc"
str_match(s, "a...") = TRUE
$0 = "a bc"
$1 = " bc"
$2 = ""

See Also

String Routines on page 1487

~ !~ on page 94

27.7.15 str_pad()
Purpose
Pad string with blanks

Category
Routine

Syntax
str_pad(str: string, length: int): string
Syntax Example
var s: string = str_pad("hello world",14);

Parameters
str

An expression of type string.

length

An integer representing the desired length, no greater than 4000.

Description
Returns a copy of the original string padded with blanks on the right, up to desired length. If the length
of the original string is greater than or equal to the desired length, then the original string is returned (not
a copy) with no padding.
Specman e Language Reference
1999-2015

1508

Product Version 15.1


All Rights Reserved.

Example
<'
extend sys {
m1() is {
var s: string = str_pad("hello world",14);
print s;
};
};
'>

Result
Specman > sys.m1()
s = "hello world
"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.16 str_replace()
Purpose
Replace a substring in a string with another string

Category
Routine

Syntax
str_replace(str: string, regular-exp: string, replacement: string): string
Syntax Example
var s: string = str_replace("crc32", "/(.*32)/", "32_flip");

Parameters
str

An expression of type string.

Specman e Language Reference


1999-2015

1509
.

Product Version 15.1


All Rights Reserved.

regular-exp

An AWK-style or native Specman regular expression. If not surrounded by


slashes, the expression is treated as a native style expression. See String
Matching on page 99 for more information on these types of expressions.

replacement

The string that you want to replace all occurrences of the regular expression.

Description
A new copy of the original string is created, and then all the matches of the regular expression are
replaced by the replacement string. If no match is found, a copy of the source string is returned.
In native Specman regular expressions, the portion of the original string that matches the * or the ...
characters is replaced by the replacement string.
In AWK-style regular expressions, you can mark the portions of the regular expressions that you want to
replace with parentheses. For example, the following regular expression marks all the characters after
on, up to and including th to be replaced.
"/on(.*th)/"

Notes

To incorporate the string matched by the regular-exp into the replacement string, use &. For
example, the following command replaces each x in xxx with xs:
Specman > out(str_replace("xxx","x","&s"))
xsxsxs

If you need to incorporate the literal ampersand character, escape it with a backslash. For example,
the following command replaces each x in xxx with &s:
Specman > out(str_replace("xxx","x","\&s"))
&s&s&s

To incorporate the matched substrings in the replacement string, use backslash escaped numbers \1,
\2, and so on. See Example 2 on page 1511 for an example.

Example 1
This example uses AWK-style string matching.
<'
extend sys {
m1() is {
var new_str : string = str_replace("testing one two \
three", "/on(.*th)/" , "f");
print new_str;
};
Specman e Language Reference
1999-2015

1510

Product Version 15.1


All Rights Reserved.

};
'>

Result
Specman > sys.m1()
new_str = "testing free"

Example 2
Another AWK-style example, using \1, \2:
<'
extend sys {
m1() is {
var new_str : string = str_replace("A saw B",
"/(.*) saw (.*)/" , "\2 was seen by \1");
print new_str;
};
};
'>

Result
Specman > sys.m1()
new_str = "B was seen by A"

Example 3
This example uses a Specman-style regular expression.
<'
extend sys {
m1() is {
var new_str: string=str_replace("abc z", "a* " , "xy");
print new_str;
};
};
'>

Result
Specman > sys.m1()
new_str = "xyz"

Specman e Language Reference


1999-2015

1511
.

Product Version 15.1


All Rights Reserved.

Example 4
This example uses a Specman-style regular expression with \1.
<'
extend sys {
m1() is {
var new_str: string=str_replace("abc ghi", "* " , "\1 def ");
print new_str;
};
};
'>

Result
Specman > sys.m1()
new_str = "abc def ghi"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.17 str_split()
Purpose
Split a string to substrings

Category
Routine

Syntax
str_split(str: string, regular-exp: string): list of string
Syntax Example
var s: list of string = str_split("first-second-third", "-");

Specman e Language Reference


1999-2015

1512

Product Version 15.1


All Rights Reserved.

Parameters
str

An expression of type string.

regular-exp

An AWK-style or native Specman-style regular expression that specifies where to


split the string. See String Matching on page 99 for more information on these
types of expressions.

Description
Splits the original string on each occurrence of the regular expression, and returns a list of strings. If the
regular expression occurs at the beginning or the end of the original string, an empty string is returned.
If the regular expression is an empty string, it has the effect of removing all blanks in the original string.

Example 1
<'
extend sys {
m1() is {
var s: list of string=str_split("one-two-three", "-");
print s;
};
};
'>

Result
Specman
s =
0.
1.
2.

> sys.m1()
"one"
"two"
"three"

Example 2
<'
extend sys {
m1() is {
var s: list of string = str_split(" A B
print s;
};
};
'>

Specman e Language Reference


1999-2015

1513
.

C", "/ +/");

Product Version 15.1


All Rights Reserved.

Result
Specman
s =
0.
1.
2.
3.

> sys.m1()
""
"A"
"B"
"C"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.18 str_split_all()
Purpose
Split a string to substrings, including separators

Category
Routine

Syntax
str_split_all(str: string, regular-exp: string): list of string
Syntax Example
var s: list of string = str_split_all(" A B C", "/ +/");

Parameters
str

An expression of type string.

regular-exp

An AWK-style or native Specman-style regular expression that specifies where to


split the string. See String Matching on page 99 for more information on these
types of expressions.

Specman e Language Reference


1999-2015

1514

Product Version 15.1


All Rights Reserved.

Description
Splits the original string on each occurrence of the regular expression, and returns a list of strings. If the
regular expression occurs at the beginning or the end of the original string, an empty string is returned.
This routine is similar to str_split(), except that it includes the separators in the resulting list of strings.

Example
<'
extend sys {
m1() is {
var s: list of string = str_split_all(" A B
print s;
};
};
'>

C", "/ +/");

Result
Specman
s =
0.
1.
2.
3.
4.
5.
6.

> sys.m1()
""
" "
"A"
" "
"B"
" "
"C"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.19 str_sub()
Purpose
Extract a substring from a string

Specman e Language Reference


1999-2015

1515
.

Product Version 15.1


All Rights Reserved.

Category
Routine

Syntax
str_sub(str: string, from: int, length: int): string
Syntax Example
var dir: string = str_sub("/rtests/test32/tmp", 8, 6);

Parameters
str

An expression of type string.

from

The index position from which to start extracting. The first character in the string
is at index 0.

length

An integer representing the number of characters to extract.

Description
Returns a substring of the specified length from the original string, starting from the specified index
position.

Example
<'
extend sys {
m1() is {
var dir: string = str_sub("/rtests/test32/tmp", 8, 6);
print dir;
};
};
'>

Result
Specman > sys.m1()
dir = "test32"

See Also

String Routines on page 1487

Specman e Language Reference


1999-2015

1516

Product Version 15.1


All Rights Reserved.

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.20 str_upper()
Purpose
Convert a string to uppercase

Category
Routine

Syntax
str_upper(str: string): string
Syntax Example
var upper: string = str_upper("lower");

Parameter
str

An expression of type string.

Description
Returns a copy of the original string, converting all lower case characters to upper case characters.

Example
<'
extend sys {
m1() is {
var upper: string = str_upper("lower");
print upper;
};
};
'>

Result
Specman > sys.m1()
Specman e Language Reference
1999-2015

1517
.

Product Version 15.1


All Rights Reserved.

upper = "LOWER"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.7.21 to_string()
Purpose
Convert any expression to a string

Category
Method

Syntax
exp.to_string(): string
Syntax Example
print pkts[0].to_string();

Parameter
exp

A legal e expression.

Description
This method can be used to convert any type to a string.
If the expression is a struct expression, the to_string() method returns a unique identification string for
each struct instance. You can use this ID to refer to the struct. In GUI mode, this ID is hyperlinked to
display the values of that struct instance. By default, the identification string is of the form type-@ num,
where num is a unique struct number over all instances of all structs in the current run.
If the expression is a list of strings, the to_string() method is called for each element in the list. The
string returned contains all the elements with a newline between each element.

Specman e Language Reference


1999-2015

1518

Product Version 15.1


All Rights Reserved.

If the expression is a list of any type except string, the to_string() method returns a string containing all
the elements with a space between each element.
If the expression is a numeric type, the expression is converted using the current radix with the radix
prefix.
If the expression is a string, the to_string() method returns the string.
If the expression is an enumerated or a Boolean type, the to_string() method returns the value.
Note Using to_string() with expressions of special types, such as untyped or external_pointer, is
not allowed and will lead to a compilation error.

Example
<'
struct pkt {
protocol: [ethernet, atm, other];
legal : bool;
data[2]: list of byte;
};
extend sys {
pkts[5]: list of pkt;
m1() is {
var slist: list of string = {"strA";"strB";"strC"};
print pkts[0].to_string();
print pkts[0].data.to_string();
print pkts[0].protocol.to_string();
print pkts[0].legal.to_string();
print slist.to_string();
};
};
'>

Result
Specman > sys.m1()
pkts[0].to_string() = "pkt-@0"
pkts[0].data.to_string() = "52 218"
pkts[0].protocol.to_string() = "atm"
pkts[0].legal.to_string() = "TRUE"
slist.to_string() = "strA
strB
strC"

Specman e Language Reference


1999-2015

1519
.

Product Version 15.1


All Rights Reserved.

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.8 Macro-Related Routines


The following routines are useful in the context of define as computed macros:

get_current_line_num() on page 1520

get_current_module() on page 1521

str_expand_dots() on page 1522

reject_match() on page 1523

27.8.1

get_current_line_num()

Purpose
Return current line number from a macro call

Category
Routine

Syntax
get_current_line_num(): int
Syntax Example
define <my_field'struct_member> "special_field" as computed {
var m_name: string = get_current_module().get_name();
if m_name !~ "/_xxx$/" then {
result = append("f_", m_name, "_",
get_current_line_num(), ": int");
};
};

Specman e Language Reference


1999-2015

1520

Product Version 15.1


All Rights Reserved.

Description
Returns the source line number in which the macro is called. The routine returns UNDEF if it is called
within a <command> macro, or if it is used from within a command rather than inside a loaded or
compiled module.
Note This routine must be called within the context of a define as computed macro, or an error is
returned.

See Also

Using the get_current_line_num() and get_current_module() Routines on page 1103

27.8.2

get_current_module()

Purpose
Return the current module from a macro call

Category
Routine

Syntax
get_current_module(): rf_module
Syntax Example
define <my_field'struct_member> "special_field" as computed {
var m_name: string = get_current_module().get_name();
if m_name !~ "/_xxx$/" then {
result = append("f_", m_name, "_",
get_current_line_num(), ": int");
};
};

Description
Returns the reflection representation of the module in which the macro is called. The routine returns
NULL if it is called within a <command> macro, or if it is used from within a command rather than
inside a loaded or compiled module.

Specman e Language Reference


1999-2015

1521
.

Product Version 15.1


All Rights Reserved.

Notes

This routine must be called within the context of a define as computed macro, or an error is returned.
This routine are called during macro expansion, at an early stage of compilation. Therefore, if you
query the rf_module object from within the macro, some information will be missing. For example,
get_type_layers() will return an empty list, even if the module has type declarations or extensions.
This information is available when the rf_module is queried from outside the macro definition,
after compilation.

See Also

Using the get_current_line_num() and get_current_module() Routines on page 1103

27.8.3

str_expand_dots()

Purpose
Expand strings shortened by the parser

Category
Routine

Syntax
str_expand_dots(str: string): string
Syntax Example
out("After expand: ",str_expand_dots(<1>));

Parameter
str

An expression of type string.

Description
Returns a copy of the original string, expanding any dot place holders into the actual code they
represent.

Specman e Language Reference


1999-2015

1522

Product Version 15.1


All Rights Reserved.

This routine is useful only in context of define as computed statements. When preprocessing an e file,
Specman converts any sequence of characters between matching brackets or quotes (such as (), [], {},
or " ") into compressed code, with dots as place holders. If you want to retrieve the original string, not
just the compressed code, you can use this routine.

Example
To retrieve the original string passed to my_macro, call the str_expand_dots() routine.
<'
define <my_macro'command> "my_macro (\
\"<string>\")" as computed {
out("Before expand: ", <1>);
out("After expand: ",str_expand_dots(<1>));
result = "{}"
};
'>

Result
Specman > my_macro "hello world"
Before expand: "10"
After expand: "hello world"

See Also

String Routines on page 1487

Table 2-7 on page 205, for information about type conversion between strings and scalars

27.8.4

reject_match()

Purpose
Restrict the syntax specified by a macro match expression

Category
Routine

Syntax
reject_match()
Specman e Language Reference
1999-2015

1523
.

Product Version 15.1


All Rights Reserved.

Syntax Example
define <multi_str_len'exp> "str_len[]\(<exp>,...\)" as computed {
if (<exps>.size()) == 1 then {
reject_match();
};
return append("str_len(append(", str_join(<exps>, ","), "))");
};

Definition
Within a define as computed macro, you can use the reject_match() routine to apply further
restrictions on the syntax specified by the match expression. This feature is useful when a match
expression cannot express the exact syntax, or when such a match expression will be less convenient or
too complicated.

See Also

Using the reject_match() Routine on page 1101

27.9 Output Routines


The predefined output routines print formatted and unformatted information to the screen and to open
log files. The following sections describe the output routines:

out() on page 1524

outf() on page 1526

Format String on page 1528

27.9.1

out()

Purpose
Print expressions to output, with a new line at the end

Category
Routine

Syntax
out()
Specman e Language Reference
1999-2015

1524

Product Version 15.1


All Rights Reserved.

out(item: exp, ...)


Syntax Example
out("pkts[1].data is

", pkts[1].data);

Parameter
item

A legal e expression. String expressions must be enclosed in double quotes. If the


expression is a struct instance, the struct ID is printed. If no item is passed to
out(), an empty string is printed, followed by a new line.

Description
Calls to_string() to convert each expression to a string and prints them to the screen (and to the log file
if it is open), followed by a new line.

Example
This first example shows that if the expression is a struct, out() prints the ID of the struct. In GUI mode,
this ID is hyperlinked to a display of the struct fields and current values. If the expression is a list, out()
prints each element of the list from left to right, starting with the element with the lowest index. If no
expression is passed, out() prints a new line.
struct pkt {
protocol: [ethernet, atm, other];
legal : bool;
data[2]: list of byte;
};
extend sys {
pkts[5]: list of pkt;
m1() is {
out();
out("ID of first packet is
out("pkts[1].data is
out("pkts[1].data[0] is
out();
};
};

", pkts[0]);
", pkts[1].data);
", pkts[1].data[0]);

Result
Specman > sys.m1()
Specman e Language Reference
1999-2015

1525
.

Product Version 15.1


All Rights Reserved.

ID of first packet is
pkts[1].data is
pkts[1].data[0] is

pkt-@0
142 170
142

See Also

outf() on page 1526

print in the Specman Command Reference

27.9.2

outf()

Purpose
Print formatted expressions to output, with no new line at the end

Category
Routine

Syntax
outf(format: string, item: exp, ...)
Syntax Example
outf("%s %#08x","pkts[1].data[0] is

", pkts[1].data[0]);

Parameters
format

A string containing a standard C formatting mask for each item. See Format
String on page 1528 for more information.

item

A legal e expression. String expressions must be enclosed in double quotes. If the


expression is a struct instance, the struct ID is printed. If the expression is a list, an
error is issued.

Description
Converts each expression to a string using the corresponding format string and then prints them to the
screen (and to the log file if it is open).

Specman e Language Reference


1999-2015

1526

Product Version 15.1


All Rights Reserved.

To add a new line, add the \n characters to the format string.

Notes

If the number and type of masks in the format string does not match the number and type of
expressions, an error is issued.
Specman adds a new line by default after 80 characters. To disable this, set the line size to UNDEF
or to a very large number with the set_config() routine.
set_config(print, line_size, UNDEF);

Example 1
This example has similar results to the in the description of out() on page 1524. Note that outf() allows
you to add the new lines where needed. Printing of lists is not supported with outf().
extend sys {
pkts[5]: list of pkt;
m1() is {
outf("%s %s\n","pkts[0] ID is
outf("%s %#x","pkts[1].data[0] is
};
};

", pkts[0]);
", pkts[1].data[0]);

Result
Specman > sys.m1()
pkts[0] ID is
pkts[1].data[0] is

pkt-@0
0x8e

Example 2
This example shows the control over formatting of strings that outf() allows. The fields have been
enclosed in double : characters so that you can easily see how wide the field is.
<'
extend sys {
m1() is {
outf(":%s:\n", "hello world");
outf(":%15s:\n", "hello world");
outf(":%-15s:\n", "hello world");
outf(":%.8s:\n", "hello world");
outf(":%08d:\n", 12);
};
};
'>
Specman e Language Reference
1999-2015

1527
.

Product Version 15.1


All Rights Reserved.

Result
Specman > sys.m1()
:hello world:
:
hello world:
:hello world
:
:hello wo:
:00000012:

See Also

out() on page 1524

print in the Specman Command Reference

27.9.3

Format String

The format string for the outf() and appendf() routines, and for the messagef() and dut_errorf()
actions, uses the following syntax:
"%[0|-][#][min_width][.max_chars](s|d|x|b|o|u)"

Note Since % is a special character indicating the start of a format string, if you want to print a
percentage, such as New Packets = 1%, you must enter the % character twice, for example:
outf("New Packets = %d%%\n", 1)

Pads with 0 instead of blanks. Padding is only done when right alignment is used,
on the left end of the expression.

Aligns left. The default is to align right.

Adds 0x before the number. Can be used only with the x (hexadecimal) format
specifier. Examples: %#x, %0#10x

min_width

A number that specifies the minimum number of characters. This number


determines the minimum width of the field. If there are not enough characters in
the expression to fill the field, the expression is padded to make it this many
characters wide. If there are more characters in the expression than this number
(and if max_chars is set large enough), this number is ignored and enough space
is used to accommodate the entire expression.

Specman e Language Reference


1999-2015

1528

Product Version 15.1


All Rights Reserved.

max_chars

A number that specifies the maximum number of characters to use from the
expression. If this number is larger than min_width, then the min_width number
is ignored.
In the following example, min_width is 7 and max_chars is 5, so the outf() method
prints five characters from abcdefghi in a field seven characters wide, padding
the two unused spaces with blanks:
> outf("%7.5s\n", "abcdefghi")
abcde

In the following example, min_width is 8 and max_chars is 3, so the outf() method


prints three characters from abcdefghi in a field eight characters wide, padding
the five unused spaces with zeros, since the 0 padding option is present
immediately after the %:
> outf("%08.3s\n", "abcdefghi")
00000abc

The max_chars parameter affects numeric expressions (conversion character is


one of d|x|b|o|u) differently than it affects string expressions (conversion character
is s). For a numeric expression, the max_chars parameter does not truncate the
expression even if the number is longer than max_chars. For example, for a string
expression:
> outf("%0#6.6s","abcd") //max_chars=6, prints 00abcd
> outf("%0#6.4s","abcd") //max_chars=4, prints 00abcd
> outf("%0#6.2s","abcd") //max_chars=2, prints 0000ab

For a hexadecimal expression:


>
>
>
>

config print -radix=HEX


outf("%0#6.6x", 0xabcd) //max_chars=6, prints 0x00abcd
outf("%0#6.4x", 0xabcd) //max_chars=4, prints 0xabcd
outf("%0#6.2x", 0xabcd) //max_chars=2, prints 0xabcd

Converts the expression to a string. The routine to_string() on page 1518 is used
to convert a non-string expression to a string.

Prints a numeric expression in decimal format.

Prints a numeric expression in hex format. With the optional # character, adds 0x
before the number, unless the number is 0, in which case only 0s are printed
without the 0x prepended.

Prints a numeric expression in binary format.

Prints a numeric expression in octal format.

Specman e Language Reference


1999-2015

1529
.

Product Version 15.1


All Rights Reserved.

Prints integers (int and uint) in uint format.

%nn.nnf

Prints a real value. Examples:


Specman> m=0.81234567890125
Specman> outf("%2.13f\n ", m)
0.8123456789012
Specman> outf("%2.14f\n ", m)
0.81234567890125

27.10 Configuration Routines


The configuration routines set options that allow you to control printing, memory usage, runtime
characteristics, coverage, generation, and debug from within the e code.
These routines have command line equivalents that are described in detail in the Specman Command
Reference.

set_config() on page 1530

get_config() on page 1535

write_config() on page 1536

read_config() on page 1538

set_retain_state() on page 1540

get_retain_state() on page 1541

27.10.1 set_config()
Purpose
Set configuration options

Category
Routine

Syntax
set_config(category: keyword, option: keyword, value: exp [, option: keyword, value: exp...]) [[with]
{action; ...}]
Specman e Language Reference
1999-2015

1530

Product Version 15.1


All Rights Reserved.

Syntax Example
set_config(print, radix, bin);

Parameters
category

Is one of the configuration command categories, such as cover[age],


data[browser], debug[ger], gen[eration], and so on. See Configuration
Commands in the Specman Command Reference for more information.

option

The valid options are different for each category. See Configuration Commands
in the Specman Command Reference for more information.

value

The valid values are different for each option and are described in the Specman
Command Reference.

Description
This form of the set_config() action sets the specified options of a particular category to the specified
values.
If an action block is specified, the options are set only temporarily during the execution of the action
block.
For the configuration options to be effective, they must be set before the run test phase. The
recommended place to use set_config() is in the sys.setup() method, as follows:
extend sys {
setup() is also {
set_config(category, option, value, ...);
};
};

Note You can use the lint_manager.get_all_set_config_actions() API to lint existing e code for
information about the use of set_config() in the code. For more information, see lint_manager API for
Getting set_config() Actions in e Linting with HAL.

Exceptions
Specifying the default generator to Pgen must be done before any e files are loaded. Therefore, you can
not use the following routine in an e file:
set_config(gen, default_generator, Pgen);

Specman e Language Reference


1999-2015

1531
.

Product Version 15.1


All Rights Reserved.

Example 1
In the following example, the setup() method is extended to set configuration options.
<'
extend sys {
setup() is also {
set_config(print, radix, bin);
set_config(cover, sorted, TRUE);
set_config(gen, seed, random, default_max_list_size,
20);
set_config(run, tick_max, 1000, exit_on, all);
set_config(memory, gc_threshold, 100m);
set_config(misc, warn, FALSE);
};
};
'>

Result
Specman > setup
Specman > show config
configuration options for: print
-radix
.
.
.
configuration options for: cover
-sorted
.
.
.
configuration options for: gen
-seed
-default_max_list_size
.
.
.
configuration options for: run
-tick_max
-exit_on
.
.
.
configuration options for: memory
-gc_threshold
.
Specman e Language Reference
1999-2015

1532

BIN

TRUE

=
=

187136885
20

=
=

1000
all

104857600

Product Version 15.1


All Rights Reserved.

.
.
configuration options for: misc
-warn
.
.
.

FALSE

Example 2
<'
struct packet {
protocol: [atm, eth];
data[10]: list of byte;
};
extend sys {
!pi: list of packet;
post_generate() is also {
set_config(gen, seed, 0xff) with {gen pi;};
};
};
'>

Example 3
The following example demonstrates the difference between setting the show_sub_holes coverage
configuration option to TRUE versus the default setting of FALSE.
Two coverage items, i1 and i2 are defined, both for Boolean fields. A cross item is also defined for the
two items.
<'
extend sys {
i1: bool;
i2: bool;
event cv;
cover cv is {
item i1;
item i2;
cross i1, i2;
};
run() is also {
emit cv;
};
};
extend sys {

Specman e Language Reference


1999-2015

1533
.

Product Version 15.1


All Rights Reserved.

setup() is also {
set_config(cover, mode, on, show_mode, both);
};
};
'>

In the test, i1 gets FALSE and i2 gets TRUE.


The cross i1, i2 section of the coverage data with show_sub_holes = FALSE is shown below. In this
example, since i1 = TRUE is an empty top bucket, the coverage report does not show the non-existent
sub-buckets for i1 = TRUE, i2 = X.
** cross__i1__i2 **
Samples: 1 Tests: 1

Grade: 0.25

grade

goal

samples

tests

0.50
0.00
1.00
0.00

1
1
-

1
0
1
0

1
0
1
0

Weight: 1
%p/%

100/100
0/0
100/100
0/0

i1/i2
FALSE
FALSE/FALSE
FALSE/TRUE
TRUE

The cross i1, i2 section of the coverage data with show_sub_holes = TRUE is shown below. In this
example, the coverage data shows the tree under the empty top bucket for i1 = TRUE, and expands the
two empty sub-buckets under it, i1/i2 = TRUE/FALSE and i1/12=TRUE/TRUE.
** cross__i1__i2 **
Samples: 1 Tests: 1

Grade: 0.25

Weight: 1

grade

goal

samples

tests

%p/%t

0.50
0.00
1.00
0.00
0.00
0.00

1
1
1
1

1
0
1
0
0
0

1
0
1
0
0
0

100/100
0/0
100/100
0/0
0/0
0/0

i1/i2
FALSE
FALSE/FALSE
FALSE/TRUE
TRUE
TRUE/FALSE
TRUE/TRUE

See Also

Configuration Routines on page 1530

set_config_max() on page 317

Specman e Language Reference


1999-2015

1534

Product Version 15.1


All Rights Reserved.

27.10.2 get_config()
Purpose
Get the configuration option settings

Category
Routine

Syntax
get_config(category: exp, option: exp)
Syntax Example
var s: int = get_config(gen, seed);

Parameters
category

Is one of the following: cover, debugger, gen, gui, memory, misc,


performance, print, run, and wave.

option

The valid options are different for each category. See Configuration Commands
in the Specman Command Reference for more information.

Description
Returns the value of the configuration option. The type of the returned value depends on the specified
option.

Example
<'
struct packet {
protocol: [atm, eth];
data[10]: list of byte;
};
extend sys {
!pi: list of packet;
post_generate() is also {
Specman e Language Reference
1999-2015

1535
.

Product Version 15.1


All Rights Reserved.

set_config(gen, seed, 0xff) with {


gen pi;
var seed: int = get_config(gen, seed);
set_config(print, radix, hex) with {
print seed;
var radix: po_radix = get_config(print, radix);
print radix;
};
};
};
};
'>

Results
cmd-prompt> test
Doing setup ...
Generating the test using seed 0x1...
seed = 0xff
radix = HEX
Starting the test ...
Running the test ...
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.

See Also

Configuration Routines on page 1530

27.10.3 write_config()
Purpose
Save configuration options in a file

Category
Routine

Syntax
write_config(filename: string)
Specman e Language Reference
1999-2015

1536

Product Version 15.1


All Rights Reserved.

Syntax Example
write_config("test25");

Parameter
filename

A string enclosed in double quotes and containing the name of a file. If a filename
is entered with no filename extension, the default extension .ecfg is used.

Description
Creates a file with the specified name and writes the current configuration options to the file.
The read_config() method can be used to read the configuration options back in from the file.

Example
<'
struct packet {
protocol: [atm, eth];
data[10]: list of byte;
};
extend sys {
pi: list of packet;
};
extend sys {
setup() is also {
set_config(print, radix, bin);
set_config(cover, sorted, TRUE);
set_config(gen, seed, random, default_max_list_size, 20);
set_config(run, tick_max, 1000, exit_on, all);
set_config(memory, gc_threshold, 100m);
set_config(misc, warn, FALSE);
write_config("test25");
};
};
'>

Result
% cat test25.ecfg
-- The top struct
struct: config_all-@0:

Specman e Language Reference


1999-2015

1537
.

Product Version 15.1


All Rights Reserved.

print: print config_options-@1:


category: print
print'radix: BIN
print'items: 0b10100
print'list_lines: 0b10100
print'list_from: 0b0
print'title: NULL
.
.
.

See Also

Configuration Routines on page 1530

write config to in the Specman Command Reference

27.10.4 read_config()
Purpose
Read configuration options from a file

Category
Routine

Syntax
read_config(filename: string)
Syntax Example
read_config("test25");

Parameter
filename

A string enclosed in double quotes and containing the name of a file. If a filename
is entered with no filename extension, the default extension .ecfg is used.

Specman e Language Reference


1999-2015

1538

Product Version 15.1


All Rights Reserved.

Description
Read configuration options from a file with the specified name. The configuration options must
previously have been written to the file using the write_config() method.

Example
<'
struct packet {
protocol: [atm, eth];
data[10]: list of byte;
};
extend sys {
pi: list of packet;
setup() is also {
read_config("test25");
};
};
'>

Result
Specman > setup
Specman > show config
configuration options for: print
-radix
.
.
.
configuration options for: cover
-sorted
.
.
.
configuration options for: gen
-seed
-default_max_list_size
.
.
.
configuration options for: run
-tick_max
-exit_on
.
.
Specman e Language Reference
1999-2015

1539
.

BIN

TRUE

=
=

908142002
20

=
=

1000
all

Product Version 15.1


All Rights Reserved.

.
configuration options for: memory
-gc_threshold
.
.
.
configuration options for: misc
-warn
.
.
.

104857600

FALSE

See Also

Configuration Routines on page 1530

read config from in the Specman Command Reference

27.10.5 set_retain_state()
Purpose
Set or reset the retain state mode

Category
Routine

Syntax
set_retain_state(bool: exp)
Syntax Example
set_retain_state(FALSE);

Parameter
bool

If TRUE, Specman keeps configuration, breakpoint, trace and watch information


across all restores and reloads. If FALSE, this information is reset at each reload
or restore, using the information from the initial .esv file instead. The default is
TRUE.

Specman e Language Reference


1999-2015

1540

Product Version 15.1


All Rights Reserved.

Description
Sets or resets the retain state mode, which controls whether configuration settings and debugger
information is retained across restores and reloads.
This routine is exactly equivalent to the retain state command.

Notes

When restoring from a specified .esv file, the retain state mode is ignored and the information is
taken from the specified .esv file.
The retain state mode itself is kept across restores and reloads, unless you are restoring from a
specified .esv file. In that case, the new retain state mode is taken from the specified .esv file.
You can override the retain state mode by using the -retain or -noretain options on the restore or
reload commands.

Example
<'
extend sys {
setup() is also {
set_retain_state(FALSE);
};
};
'>

See Also

get_retain_state() on page 1541

set retain state in the Specman Command Reference

show retain state in the Specman Command Reference

restore in the Specman Command Reference

reload in the Specman Command Reference

27.10.6 get_retain_state()
Purpose
Retrieve the value of the retain state mode

Specman e Language Reference


1999-2015

1541
.

Product Version 15.1


All Rights Reserved.

Category
Routine

Syntax
get_retain_state(): bool
Syntax Example
print get_retain_state();

Description
Retrieves the value of the retain state mode, which controls whether configuration settings and
debugger information is retained across restores and reloads.
This method is similar to the show retain state command.

Example
<'
extend sys {
setup() is also {
print get_retain_state();
set_retain_state(TRUE);
print get_retain_state();
};
};
'>

Result
cmd-prompt> setup
Doing setup ...
get_retain_state() = FALSE
get_retain_state() = TRUE

See Also

set_retain_state() on page 1540

set retain state in the Specman Command Reference

show retain state in the Specman Command Reference

restore in the Specman Command Reference

Specman e Language Reference


1999-2015

1542

Product Version 15.1


All Rights Reserved.

reload in the Specman Command Reference

27.11 Agent-Related Routine


27.11.1 agent_command()
Purpose
Issue a command to the agent of the current unit

Category
Predefined routine

Syntax
agent_command(command: string)
Syntax Example
agent_command("bar(magic(3))");

Parameters
command

An expression of type string represetning a valid agent command. Commands that


change the state of simulation, such as run, restart, restore, or exit, cannot be passed to
the agent with agent_command().

Description
Passes a command to the agent of the current unit from e. The routine returns no value. The output of the
routine may be sent to standard output and/or to the log file, depending on the agent.
Notes

You cannot pass force or deposit agent commands to a simulator agent with this routine.
If the agent is VCS, agent_command() is supported with the UCLI (Unified Command Line
Interface) debugging tool only. agent_command() is not supported with the CLI tool.
Simulator commands that advance timelike run, next, step, continue, or finishcannot be executed
via agent_command().

Specman e Language Reference


1999-2015

1543
.

Product Version 15.1


All Rights Reserved.

Agent commands that result in an action in the context of Specmansuch as reset or restart, for
examplemay result in undefined behavior. Such commands should not be used with
agent_command().

Example
agent_command("bar(magic(3))");

27.12 Specman Command Routine


27.12.1 specman()
Purpose
Send Specman commands from within actions

Category
Routine

Syntax
specman()
specman(command: string, ...)
Syntax Example
specman("break on tcm_start");

Parameter
command

A Specman command, with or without parameters and enclosed in double quotes.


Calling specman() with commands that change state, including restore, load,
and reload, results in an error.

Description
This routine concatenates all the commands into one string and then executes the string as a Specman
command.
Specman e Language Reference
1999-2015

1544

Product Version 15.1


All Rights Reserved.

Example
A typical use of the specman() routine is to set defaults for a test. Calls to the specman() routine can be
placed in the sys.setup() method:
extend sys {
setup() is also {
specman("set radix hex");
specman("break on tcm_start");
};
};

Result
Specman > setup
Doing setup ...
2. break on tcm_start *.*

27.13 OS Interface Routines


The routines in this section enable use of operating system commands from within the e programming
language. These routines work on all supported operating systems.
The OS interface routines in this section are:

spawn() on page 1545

spawn_check() on page 1547

system() on page 1548

output_from() on page 1549

output_from_check() on page 1551

get_symbol() on page 1552

date_time() on page 1553

getpid() on page 1554

27.13.1 spawn()
Purpose
Send commands to the operating system

Specman e Language Reference


1999-2015

1545
.

Product Version 15.1


All Rights Reserved.

Category
Pseudo-routine

Syntax
spawn()
spawn(command: string, ...)
Syntax Example
spawn("touch error.log;","grep Error specman.elog > error.log");

Parameter
command

An operating system command, with or without parameters and enclosed in


double quotes.

Description
Takes a variable number of parameters, concatenates them together, and executes the string result as an
operating system command via system().
Running spawn() in IES-XL GUI Mode
In IES-XL GUI mode:

The following code runs the command and prints output of all programs run by the command.
(including the output of background processes invoked by command).
spawn ("command")

The following code runs the command in background and returns immediately. All output of the
command is lost.
spawn ("command&")

In both cases, spawn() does not support programs that read standard input.

Example
<'
extend sys {
m1() is {
spawn("touch error.log;","grep Error specman.elog > \
error.log");
};
Specman e Language Reference
1999-2015

1546

Product Version 15.1


All Rights Reserved.

};
'>

See Also

OS Interface Routines on page 1545

shell in the Specman Command Reference

27.13.2 spawn_check()
Purpose
Send a command to the operating system and report error

Category
Routine

Syntax
spawn_check(command: string)
Syntax Example
spawn_check("grep Error specman.elog >& error.log");

Parameter
command

A single operating system command, with or without parameters and enclosed in


double quotes.

Description
Executes a single string as an operating system command via system(), then calls error() if the
execution of the command returned an error status.

Example
<'
extend sys {
m1() is {
spawn_check("grep Error specman.elog >& error.log");
Specman e Language Reference
1999-2015

1547
.

Product Version 15.1


All Rights Reserved.

};
};
'>

Result
Specman > sys.m1()
*** Error: Error while executing 'spawn_check("grep Error specman.elog
>& error.log")'

See Also

OS Interface Routines on page 1545

shell in the Specman Command Reference

27.13.3 system()
Purpose
Send a command to the operating system

Category
Routine

Syntax
system(command: string): int
Syntax Example
stub = system("cat specman.v");

Parameter
command

A single operating system command, with or without parameters and enclosed in


double quotes.

Description
Executes the string as an operating system command using the C system() call and returns the result.

Specman e Language Reference


1999-2015

1548

Product Version 15.1


All Rights Reserved.

The return value is divided into two parts:

The lower byte returns 1 if system() fails, (for example, if it could not fork) or 0 if system() succeeds.

The upper byte is the return value of the command given to system().

Example
<'
extend sys {
m1() is {
var stub: int;
stub = system("cat specman.v");
print stub;
};
};
'>

Result
Specman > sys.m1()
/* specman.v - A Specman stubs file (top module is sim19_b) */
/* Generated automatically on Fri Mar 19 11:27:40 1999 */
module specman;
parameter sn_version_id = 0; /* Version */
parameter sn_version_date = 31198; /* Version date*/
...

See Also

OS Interface Routines on page 1545

shell in the Specman Command Reference

27.13.4 output_from()
Purpose
Collect the results of a system call

Specman e Language Reference


1999-2015

1549
.

Product Version 15.1


All Rights Reserved.

Category
Routine

Syntax
output_from(command: string): list of string

Syntax Example
log_list = output_from("ls *log");

Parameter
command

A single operating system command, with or without parameters and enclosed in


double quotes.

Description
Executes the string as an operating system command and returns the output as a list of string. Under
UNIX, stdout and stderr go to the string list.

Example
<'
extend sys {
m1() is {
var log_list: list of string;
log_list = output_from("ls *log");
print log_list;
};
};
'>

Result
Specman > sys.m1()
log_list =
0.
"specman.elog"
1.
"specview_specman.elog"

Specman e Language Reference


1999-2015

1550

Product Version 15.1


All Rights Reserved.

See Also

OS Interface Routines on page 1545

shell in the Specman Command Reference

27.13.5 output_from_check()
Purpose
Collect the results of a system call and check for errors

Category
Routine

Syntax
output_from_check(command: string): list of string

Syntax Example
log_list = output_from_check("ls *.log");

Parameter
command

A single operating system command with or without parameters and enclosed in


double quotes.

Description
Executes the string as an operating system command, returns the output as a list of string, and then calls
error() if the execution of the command returns an error status. Under UNIX, stdout and stderr go to
the string list.

Example
<'
extend sys {
m1() is {
var log_list: list of string;
log_list = output_from_check("ls *.log");
Specman e Language Reference
1999-2015

1551
.

Product Version 15.1


All Rights Reserved.

print log_list;
};
};
'>

Result
Specman > sys.m1()
*** Error: Error from system command "ls *.log":
No match

See Also

OS Interface Routines on page 1545

shell in the Specman Command Reference

27.13.6 get_symbol()
Purpose
Get UNIX environment variable

Category
Routine

Syntax
get_symbol(env-variable: string): string
Syntax Example
current_dir = get_symbol("PWD");

Parameter
env-variable

A UNIX environment variable enclosed in double quotes.

Description
Returns the environment variable as a string.

Specman e Language Reference


1999-2015

1552

Product Version 15.1


All Rights Reserved.

Example
<'
extend sys {
m1() is {
var current_dir: string;
current_dir = get_symbol("PWD");
print current_dir;
};
};
'>

Result
Specman > sys.m1()
current_dir = "/users3/sawa/docs/314/code"

See Also

OS Interface Routines on page 1545

shell in the Specman Command Reference

27.13.7 date_time()
Purpose
Retrieve current date and time

Category
Routine

Syntax
date_time(): string
Syntax Example
print date_time();

Description
Returns the current date and time as a string.
Specman e Language Reference
1999-2015

1553
.

Product Version 15.1


All Rights Reserved.

Example
cmd-prompt> print date_time()
date_time() = "Tue Jul 27 13:10:43 1999"

See Also

OS Interface Routines on page 1545

shell in the Specman Command Reference

27.13.8 getpid()
Purpose
Retrieve process ID

Category
Routine

Syntax
getpid(): int
Syntax Example
print getpid();

Description
Returns the current process ID as an integer.

Example
cmd-prompt> print getpid()
getpid() = 25517

See Also

OS Interface Routines on page 1545

Specman e Language Reference


1999-2015

1554

Product Version 15.1


All Rights Reserved.

27.14 File Routines


The global struct named files contains predefined routines for working with files. This chapter contains
information about using files and the predefined file routines. Like most global objects, the predefined
routines in the files struct are not meant to be extended with is also or is only.
General information about working with files is provided in the following sections.

File Names and Search Paths on page 1555

File Descriptors on page 1556

File Access after a Save/Restore on page 1556

Syntax for the predefined file routines is described in the following sections.

Low-Level File Routines on page 1556

General File Routines on page 1571

Reading and Writing Structs on page 1599

See Also

File Iteration Actions on page 581

String Routines on page 1487

27.14.1 File Names and Search Paths


Many of the file routines require a file-name parameter. The following are restrictions on file-name
parameters for most routines.

The file-name must be the exact path to the file.


You cannot use ~, or wild card patterns, or any environment variable, including $SPECMAN_PATH,
in the file-name.
For files that have default extensions, such as .e or .ecom, leave the extension off the file-name.

The exception to the above restrictions is the files.add_file_type() routine. This routine accepts ~, wild
cards (*), or $SPECMAN_PATH as a file-name parameter (see add_file_type() on page 1572). Before
you use any of the file routines, it is recommended that you use files.add_file_type() to make sure you
have a valid path to a file.

Specman e Language Reference


1999-2015

1555
.

Product Version 15.1


All Rights Reserved.

27.14.2 File Descriptors


For every open file, a file descriptor struct exists which contains information about the file. The routine
open() on page 1561 returns the file descriptor as a variable of type file. The name of the file variable is
used in low-level file operations such as the files.read(), files.write() and files.flush() routines. These
routines are described in Low-Level File Routines on page 1556.
Note Although the type file can be used for a variable or field, it is not generatable. Explicitly
generating a field of type file results in an error. Using such a field in a constraint may not generate an
error, but is meaningless.

27.14.3 File Access after a Save/Restore


Be aware of the issues that might arise when, after a Specman save or restore, you re-access a file that
you had been working with before the save or restore.
Assume that you have opened the file foo.txt for reading:
var f:file = files.open("foo.txt", "r", "Text File");

Assume also:

The file has 1000 characters and you have read 530 characters.

At this point, you save the Specman state and consequently restore it.

If, at this point, you try to read from the file:


var s:string;
var b:bool = files.read(f, s)

A number of different scenarios could happen:

Scenario 1: The file still exists as before. In this case, you will read starting from the 531th character
in the file, and the method will return TRUE.
Scenario 2: Someone has removed the file. In this case, you will get an error stating that the file does
not exists, and the method will return FALSE.
Scenario 3: Someone has changed the file and it now only has 468 characters. Because at the time
of the restore the next character to be read was number 531 and because this character does not exist
anymore, you will start reading from the end of the file. This will cause s to be an empty string,
and the value returned will be FALSE.

27.14.4 Low-Level File Routines


This section contains descriptions of the file routines that use file descriptor structs.

Specman e Language Reference


1999-2015

1556

Product Version 15.1


All Rights Reserved.

To write strings to a file, the simplest routine is write_string_list() / write_compressed_string_list()


on page 1597.
The following file routines are described in this section.

close() on page 1557

flush() on page 1559

open() on page 1561

read() on page 1563

read_lob() on page 1564

read_into_lob() on page 1566

write() on page 1568

write_lob() on page 1569

See Also

File Routines on page 1555

General File Routines on page 1571

Reading and Writing Structs on page 1599

27.14.4.1 close()
Purpose
Close a file

Category
Method

Syntax
files.close(file: file-descriptor)

Syntax Example
files.close(f_desc);

Specman e Language Reference


1999-2015

1557
.

Product Version 15.1


All Rights Reserved.

Parameter
file

The file descriptor of the file to be closed.

Description
Flushes the file buffer and closes the file specified by file-descriptor. The file must previously have been
opened using open() on page 1561. When no further activity is planned for a file, it should be closed to
prevent unintentional operations on its contents.

Example
The WrAndFlush() user-defined method in the following example opens a file named ex_file.txt as
the m_file variable, writes a line to the file, and then closes the file. The RFile() user-defined method
then opens the same file for reading and reads its contents into the m_string variable.
The files.flush() routine writes the AaBaCa 0123 string to the disk immediately, so that the read
routine can read it. If there were no files.close() routine (or files.flush() routine) following the write, the
data would not be in disk file when the read was done.
struct f_s_1 {
WrAndFlush(ex_file: string) is {
var m_file: file;
m_file = files.open(ex_file, "w", "Text file");
files.write(m_file, "AaBaCa 0123");
files.close(m_file);
};
RFile(ex_file: string) is {
var m_file: file;
m_file = files.open(ex_file, "r", "Text file");
var r_chk: bool;
var m_string: string;
r_chk = files.read(m_file, m_string);
if r_chk then {print m_string}
else {out("file not read")};
};
};
extend sys {
f_si_1: f_s_1;
run() is also {
f_si_1.WrAndFlush("ex_file.txt");
f_si_1.RFile("ex_file.txt");
};
};

Specman e Language Reference


1999-2015

1558

Product Version 15.1


All Rights Reserved.

See Also

open() on page 1561

flush() on page 1559

27.14.4.2 flush()
Purpose
Flush file buffers

Category
Method

Syntax
files.flush(file: file-descriptor)
Syntax Example
files.flush(a_file);

Parameter
file

The file descriptor of the file to flush.

Description
Flushes all the operating system buffers associated with file to the disk.
File data is buffered in memory and only written to disk at certain times, such as when the file is closed.
This routine causes data to be written to the disk immediately, instead of later when the file is closed.
This can be useful if two processes are using the same disk file, for example, to make sure that the
current data from one process is written to the file before the other process reads from the file.

Specman e Language Reference


1999-2015

1559
.

Product Version 15.1


All Rights Reserved.

Example
The WrAndFlush() user-defined method in the following example opens a file named ex_file.txt as
the m_file variable, writes a line to the file, and then flushes the files buffer to disk. The RFile()
user-defined method then opens the same file for reading and reads its contents into the m_string
variable.
The files.flush() routine writes the AaBaCa 0123 string to the disk immediately, so that the read
routine can read it. If there were no files.flush() routine (or file.close() routine) following the write, the
data would not be in disk file when the read was done.
struct f_s_2 {
WrAndFlush(ex_file: string) is {
var m_file: file;
m_file = files.open(ex_file, "w", "Text file");
files.write(m_file, "AaBaCa 0123");
files.flush(m_file);
};
RFile(ex_file: string) is {
var m_file: file;
m_file = files.open(ex_file, "r", "Text file");
var r_chk: bool;
var m_string: string;
r_chk = files.read(m_file, m_string);
if r_chk then {print m_string}
else {out("file not read")};
};
};
extend sys {
f_si_2: f_s_2;
run() is also {
f_si_2.WrAndFlush("ex_file.txt");
f_si_2.RFile("ex_file.txt");
};
};

See Also

open() on page 1561

flush() on page 1559

Specman e Language Reference


1999-2015

1560

Product Version 15.1


All Rights Reserved.

27.14.4.3 open()
Purpose
Open a file for reading or writing or both

Category
Method

Syntax
files.open(file-name: string, mode: string, file-role: string): file
Syntax Example
var m_file: file;
m_file = files.open("a_file.txt", "r", "Text File");

Parameters
file-name

The name of the file to open. Wild cards, ~, and $SPECMAN_PATH are not
allowed in the file name. To use them to select files, see add_file_type() on page
1572.

mode

The read/write mode for the file. The mode can be one of the following.

r[z] - open the file for reading.


w[z] - open the file for writing (overwrite the existing contents)
rw - open the file for reading and writing (add to the end of the existing
contents)
a[z] - open the file for appending (add to the end of the existing contents)

Note
file-role

A z appended to the modes r, w, a indicate a compressed file.

A text description used in error messages about the file.

Description
Opens the file for reading, writing, both reading and writing, or append, according to mode (r, w, rw, a)
and returns the file descriptor of the file.
The file-role is a description of the file, for example, source file.
If the file cannot be opened, an error like the following is issued.
Specman e Language Reference
1999-2015

1561
.

Product Version 15.1


All Rights Reserved.

*** Error: Cannot open file-role 'file-name' for mode

Compressed Files
If the file is compressed using the standard Lempel-Ziv coding, append the letter z to the r, w, or a
mode, for example rz. Compressed files usually takes up much less disk space.
If you open for reading a non-compressed file with a compressed mode (for example rz), Specman
reads the file correctly. Therefore, you can use a compressed mode to open the file even if you are unsure
whether it is compressed.

Example 1
The following example opens a file named /users/a_file.txt in write mode as file variable m_file,
writes a line to the file, and then closes the file.
struct f_3_str {
RdWrFile(ex_file: string) is {
var m_file: file;
m_file = files.open(ex_file, "w", "Text file");
files.write(m_file, "HEADER");
files.close(m_file);
};
};
extend sys {
fi_3: f_3_str;
run() is also {
fi_3.RdWrFile("/users/a_file.txt");
};
};

Example 2
The following actions, entered at the command line, perform the same operations as Example 1 above,
but writes the file as a compressed file.
var m_file: file;
m_file = files.open("/users/a_file.txt", "wz", "Text file");
files.write(m_file, "HEADER");
files.close(m_file);

See Also

add_file_type() on page 1572

close() on page 1557

Specman e Language Reference


1999-2015

1562

Product Version 15.1


All Rights Reserved.

write() on page 1568

File Access after a Save/Restore on page 1556

27.14.4.4 read()
Purpose
Read an ASCII line from a file

Category
Method

Syntax
files.read(file: file-descriptor, string-var: *string): bool
Syntax Example
r_b = files.read(f_desc, m_string);

Parameters
file

The file descriptor of the file that contains the text to read.

string-var

A variable into which the ASCII text will be read.

Description
Reads a line of text from a file into a string variable in Specman. The file must have been opened with
open() on page 1561. The line from the file is read into the Specman variable without the final \n
newline character.
The routine returns TRUE on success. If the method cannot read a line (for example, if the end of the file
is reached), it returns FALSE.
The files.read() routine is a low level routine. For performance considerations, it is generally
recommended to use the for each line in file action, rather than this routine.

Specman e Language Reference


1999-2015

1563
.

Product Version 15.1


All Rights Reserved.

Example
The following example opens a file named a_file.txt as variable m_f, reads lines one by one from the
file into a variable named m_string, and displays each string as it reads it.
struct f_s_3 {
RFile(ex_file: string) is {
var m_file: file;
m_file = files.open(ex_file, "r", "Text file");
var r_chk: bool;
var m_string: string;
r_chk = files.read(m_file, m_string);
out("The first line is: ", m_string);
while files.read(m_file, m_string) {
out("The next line is: ", m_string);
};
files.close(m_file);
};
};
extend sys {
f_si_3: f_s_3;
run() is also {
f_si_3.RFile("ex_file.txt");
};
};

See Also

for each line in file on page 581

open() on page 1561

read_lob() on page 1564

read_ascii_struct() on page 1599

read_binary_struct() on page 1601

Table 2-6 on page 202, for information about type conversion between scalar types

File Access after a Save/Restore on page 1556

27.14.4.5 read_lob()
Purpose
Read from a binary file into a list of bits

Specman e Language Reference


1999-2015

1564

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
files.read_lob(file: file-descriptor, size-in-bits: int) : list of bit
Syntax Example
var m_file: file = files.open("a_file.dat", "r", "Data");
var b_l: list of bit;
b_l = files.read_lob(m_file, 32);

Parameters
file

The file descriptor of the file to read from.

size-in-bits

The number of bits to read. Should be a multiple of 8

Description
Reads data from a binary file into a list of bits and returns the list of bits. The file must already have been
opened with open() on page 1561. To read an entire file, use UNDEF as the size-in-bits.

Example 1
The following example opens a file named a_file.dat with the file descriptor m_f, and reads the first
16 bits from the file into a list of bits named b_list.
struct f_4 {
b_list: list of bit;
RdLOB(ex_file: string) is {
var m_f: file = files.open(ex_file, "r", "Data");
b_list = files.read_lob(m_f, 16);
files.close(m_f);
};
};
extend sys {
fi_4: f_4;
run() is also {
fi_4.RdLOB("a_file.dat");
};
};

Specman e Language Reference


1999-2015

1565
.

Product Version 15.1


All Rights Reserved.

Example 2
The following actions entered at the command line perform the same operations as Example 1, above.
var m_f: file = files.open("a_file.dat", "r", "data file");
var b_list: list of bit = files.read_lob(m_f, 16);
files.close(m_f);

See Also

read_lob() on page 1564

close() on page 1557

write_lob() on page 1569

Table 2-6 on page 202, for information about type conversion between scalar types

File Access after a Save/Restore on page 1556

27.14.4.6 read_into_lob()
Purpose
Read from a binary file into a list of bits

Category
Method

Syntax
files.read_into_lob(file: file-descriptor, size-in-bits: int, result-list: list of bit)
Syntax Example
var m_file: file = files.open("a_file.dat", "r", "Data");
var b_l: list of bit;
b_l = files.read_into_lob(m_file, 32, b_l);

Parameters
file

The file descriptor of the file to read from.

size-in-bits

The number of bits to read. Should be a multiple of 8

Specman e Language Reference


1999-2015

1566

Product Version 15.1


All Rights Reserved.

result-list

The list into which to put the bits

Description
Reads data from a binary file into a list of bits and puts the bits into the list passed as a parameter.
This method is similar to read_lob(). Although it is less convenient to use from a programming
perspective, it is more efficient memory-wise because it reuses the previously allocated memory of the
list.
The file must already have been opened with open() on page 1561. To read an entire file, use UNDEF
as the size-in-bits.

Example 1
The following example opens a file named a_file.dat with the file descriptor m_f, and reads the first
16 bits from the file into a list of bits named b_list.
struct f_4 {
b_list: list of bit;
RdLOB(ex_file: string) is {
var m_f: file = files.open(ex_file, "r", "Data");
files.read_into_lob(m_f, 16, b_list);
files.close(m_f);
};
};
extend sys {
fi_4: f_4;
run() is also {
fi_4.RdLOB("a_file.dat");
};
};

Example 2
The following actions entered at the command line perform the same operations as Example 1, above.
var m_f: file = files.open("a_file.dat", "r", "data file");
var b_list: list of bit
files.read_into_lob(m_f, 16, b_list);
files.close(m_f);

See Also

close() on page 1557

Specman e Language Reference


1999-2015

1567
.

Product Version 15.1


All Rights Reserved.

open() on page 1561

read_lob() on page 1564

write_lob() on page 1569

Table 2-6 on page 202, for information about type conversion between scalar types

File Access after a Save/Restore on page 1556

27.14.4.7 write()
Purpose
Write a string to file

Category
Method

Syntax
files.write(file: file-descriptor, text: string)
Syntax Example
files.write(m_file, "Test Procedure");

Parameters
file

The file descriptor of the file to write into.

text

The text to write to the file.

Description
Adds a string to the end of an existing, open file. A new-line \n is added automatically at the end of the
string. The file must already have been opened using open() on page 1561. If the file is not open, an
error message is issued.
If the file is opened in write mode (w), this routine overwrites the existing contents. To avoid
overwriting the existing file, open it in append mode (a).

Specman e Language Reference


1999-2015

1568

Product Version 15.1


All Rights Reserved.

Note
The >> concatenation operator can be used to append information to the end of a file. For example, the
following set log command concatenates information logged for the current test onto the end of the
previously written file named test_a.elog.
set log >> test_a.elog

Example
The following example opens a file named /users/a_file.txt in write mode as file variable m_file,
writes two lines to the file, and then closes the file.
struct f_s_5 {
WrFile(ex_file: string) is {
var m_file: file;
m_file = files.open(ex_file, "w", "Text file");
files.write(m_file, "FILE 1");
files.write(m_file, "Test 1");
files.close(m_file);
};
};
extend sys {
f_si_5: f_s_5;
run() is also {
f_si_5.WrFile("/users/a_file.txt");
};
};

See Also

close() on page 1557

open() on page 1561

writef() Pseudo-Method on page 1294

File Access after a Save/Restore on page 1556

27.14.4.8 write_lob()
Purpose
Write a list of bits to a binary file

Specman e Language Reference


1999-2015

1569
.

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
files.write_lob(file: file-descriptor, bit-list: list of bit)
Syntax Example
var m_file: file = files.open("a_f.dat", "w", "My data");
var b_l: list of bit;
files.write_lob(m_file, b_l);

Parameters
file

The file descriptor of the file to write into.

bit-list

A list of bits to write to the file. The size of the list must be a multiple of 8 bits.

Description
Writes all the bits in the bit list (whose size should be a multiple of 8) to the end of the file specified by
file. The file must already have been opened with open() on page 1561.
Lists of bits are always written in binary format.

Example
The following example opens a file named a_file.dat as file descriptor m_f_1 in write mode (w). The
files.write_lob() routine writes the contents of a list of bits named b_list into the file.
The files.read_lob() routine reads the contents of the file into a variable named b_2 as a list of bits,
which is then printed.
struct f_5_str {
RdWrLOB(ex_file: string) is {
var b_list: list of bit = {1; 0; 1; 1; 0; 1 ;1; 1};
var m_f_1: file = files.open(ex_file, "w", "Data");
files.write_lob(m_f_1, b_list);
files.close(m_f_1);
var b_2: list of bit;
var m_f_2: file = files.open(ex_file, "r", "Data");
b_2 = files.read_lob(m_f_2, 8);
print b_2 using radix=bin, list_starts_on_right=FALSE;
Specman e Language Reference
1999-2015

1570

Product Version 15.1


All Rights Reserved.

};
};
extend sys {
fi_5: f_5_str;
run() is also {
fi_5.RdWrLOB("a_file.dat");
};
};

The print action in the example above displays the following.


b_2 =

(8 items, bin):
0. 1 0 1 1 0 1 1 1

See Also

close() on page 1557

open() on page 1561

read_lob() on page 1564

File Access after a Save/Restore on page 1556

27.14.5 General File Routines


These sections contains descriptions of the following routines.

add_file_type() on page 1572

file_age() on page 1574

file_append() on page 1576

file_copy() on page 1577

file_delete() on page 1579

file_exists() on page 1580

file_extension() on page 1582

file_is_dir() on page 1583

file_is_link() on page 1584

file_is_readable() on page 1586

file_is_regular() on page 1587

file_is_temp() on page 1588

file_is_text() on page 1590

file_rename() on page 1591

Specman e Language Reference


1999-2015

1571
.

Product Version 15.1


All Rights Reserved.

file_size() on page 1592

flush_log_file() on page 1594

get_text_lines() on page 1595

new_temp_file() on page 1596

write_string_list() / write_compressed_string_list() on page 1597

See Also

File Routines on page 1555

Low-Level File Routines on page 1556

Reading and Writing Structs on page 1599

27.14.5.1 add_file_type()
Purpose
Get a file name

Category
Method

Syntax
files.add_file_type(file-name: string, file-ext: string, exists: bool): string
Syntax Example
var fv: string;
fv = files.add_file_type("fname", ".e", FALSE);

Parameters
file-name

The name of the file to access. A wild card pattern can be used.

file-ext

The file extension, including the dot (.) may be empty.

exists

Sets checking for existence of the file.

Specman e Language Reference


1999-2015

1572

Product Version 15.1


All Rights Reserved.

Description
Returns a string holding the file name.
This routine assigns a string consisting of file-name and file-ext to a string variable. If file-name already
contains an extension, then file-ext is ignored. If file-ext is empty, the file-name is used with no
extension.
If exists is FALSE, the routine returns the file-name string without checking for the existence of the file.
Wild cards, ~, and $SPECMAN_PATH are not evaluated.
If exists is TRUE, Specman checks to see if there is a file that matches the file-name in the current
directory. The file-name can contain ~, $SPECMAN_PATH, and * wild cards. The * wild card
represents any combination of ASCII characters. If there is one and only one file that matches the
file-name pattern, the file's name is returned. If there is no match in the current directory, then Specman
searches the $SPECMAN_PATH directories for the file. If no matching file can be found, or if more than
one file is found in a directory that matches a wild card, an error is issued. If there are multiple matching
files in different directories in the SPECMAN_PATH, the first one found is returned.

Examples
For the following examples, assume files named ex_file and ex_file.tmp exist in the current
directory, and a file named ex_file.e exists under /prog/specman/docs (which is included in the
$SPECMAN_PATH definition).
The following assigns ex_file.e to the f1 variable, without checking to see if the ex_file.e file exists.
struct f_str {
!file_list: list of string;
AppendFileToList(ex_file: string) is {
var f1: string;
f1 = files.add_file_type(ex_file, ".e", FALSE);
file_list.add(f1);
};
};
extend sys {
fi: f_str;
run() is also {
fi.AppendFileToList("ex_file");
};
};

The following statement tries to assign ex_file.e to the f2 variable, but issues an error when it checks for
the existence of ex_file.e.
AppendFileToList(ex_file: string) is {
var f2: string;
Specman e Language Reference
1999-2015

1573
.

Product Version 15.1


All Rights Reserved.

f2 = files.add_file_type(ex_file, ".e", TRUE);


file_list.add(f2);
};

The error is shown below.


*** Error: No match for file 'ex_file.e'

The following action, entered at the command line, assigns ex_file to the f3 variable.
var f3: string = files.add_file_type("ex_file", "", TRUE);

Although ex_file.e does not exist in the current directory, it does exist in the /prog/specman/docs
directory, which is in the $SPECMAN_PATH. Therefore, the following action assigns
/prog/specman/docs/ex_file.e to the f4 variable.
var f4: string = files.add_file_type("ex_file", ".e", TRUE);

The following action assigns ex* to the f5 variable.


var f5: string = files.add_file_type("ex*", "", FALSE);

The following action checks for files that match the ex* pattern.
var f6: string = files.add_file_type("ex*", "", TRUE);

Since more than one file in the current directory matches the pattern, the names of the matching files are
printed and an error is issued:
ex_file
ex_file.tmp
There is more than one file matching ex*

See Also

file_exists() on page 1580

27.14.5.2 file_age()
Purpose
Get a files modification date

Category
Method

Specman e Language Reference


1999-2015

1574

Product Version 15.1


All Rights Reserved.

Syntax
files.file_age(file-name: string): int
Syntax Example
var f_data: int;
f_data = files.file_age("f.txt");

Parameter
file-name

The file whose age is to be found.

Description
Returns the modification date of the file as an integer. This routine can be used to compare the
modification dates of files. The integer returned by the routine is not recognizable as a date, but is a
unique number derived from the files modification date. If the modification date includes the time of
day, the time is factored into the number the routine returns. Newer files produce larger numbers than
older files.
If the file does not exist, an error like the following is issued.
*** Error: Internal error in file_age: 'file-name' does not exist

Example
In the following example, the files.file_age() routine derives a number from the modification date of a
file whose variable is my_f. The routine is called twice in the run() method in the sys extension, once
for each of two files. The age numbers are printed and compared to find the largest.
struct f_6_str {
FAge(ex_file: string): int is {
var my_f: string;
var my_age: int;
my_f = files.add_file_type(ex_file, "", TRUE);
my_age = files.file_age(my_f);
outf("file name: %s, age: %d\n", ex_file, my_age);
return my_age;
}
};
extend sys {
fi_6: f_6_str;
run() is also {
var my_age_1: int = fi_6.FAge("f_1.e");
var my_age_2: int = fi_6.FAge("f_2.e");
Specman e Language Reference
1999-2015

1575
.

Product Version 15.1


All Rights Reserved.

var oldest: int = max(my_age_1, my_age_2);


print oldest;
};
};

The example above prints the following.


file name: f_1.e, age: 927860670
file name: f_2.e, age: 927860675
oldest = 927860675

See Also

add_file_type() on page 1572

27.14.5.3 file_append()
Purpose
Append files

Category
Method

Syntax
files.file_append(from-file-name: string, to-file-name: string)
Syntax Example
files.file_append(f_1, f_2);

Parameters
from-file-name

The name of the file that will be appended to the to-file.

to-file-name

The name of the file to which the from-file will be appended.

Description
Adds the contents of the file named from-file-name to the end of the file named to-file-name. If either of
the files does not exist, an error is issued.

Specman e Language Reference


1999-2015

1576

Product Version 15.1


All Rights Reserved.

Note
The >> concatenation operator can be used to append information to the end of a file. For example, the
following set log command concatenates information logged for the current test onto the end of the
previously written file named test_a.elog.
set log >> test_a.elog

Example
The following example appends the contents of f_2.txt to the end of f_1.txt.
struct f_7_str {
FAppend(ex_file_1: string, ex_file_2: string) is {
var my_f_1: string;
my_f_1 = files.add_file_type(ex_file_1, ".txt", TRUE);
var my_f_2: string;
my_f_2 = files.add_file_type(ex_file_2, ".txt", TRUE);
files.file_append(my_f_1, my_f_2);
}
};
extend sys {
fi_7: f_7_str;
run() is also {
fi_7.FAppend("f_2.txt", "f_1.txt");
};
};

See Also

add_file_type() on page 1572

27.14.5.4 file_copy()
Purpose
Create a copy of a file

Category
Method

Specman e Language Reference


1999-2015

1577
.

Product Version 15.1


All Rights Reserved.

Syntax
files.file_copy(from-file-name: string, to-file-name: string)
Syntax Example
files.file_copy("file_1.txt", "tmp_file.txt");

Parameters
from-file-name

The name of the file to copy.

to-file-name

The name of the copy of the file.

Description
Makes a copy of the file named from-file-name, with the name to-file-name. If a files already exists with
the to-file-name, the contents of that file are replaced by the contents of the file named from-file-name.
If the file named from-file-name does not exist, an error is issued.

Example
The following example copies the contents of f_1.txt into f_1.bak.
struct f_str_8 {
FCp(ex_file_1: string, ex_file_2:string) is {
files.file_copy(ex_file_1, ex_file_2);
};
};
extend sys {
fi_8: f_str_8;
run() is also {
fi_8.FCp("f_1.txt", "f_1.bak");
};
};

See Also

file_rename() on page 1591

Specman e Language Reference


1999-2015

1578

Product Version 15.1


All Rights Reserved.

27.14.5.5 file_delete()
Purpose
Delete a file

Category
Method

Syntax
files.file_delete(file-name: string)
Syntax Example
files.file_delete("run_1.log");

Parameter
file-name

The file to be deleted.

Description
Deletes a specified file. If the file cannot be found, an error like the following is issued.
*** Error: No match for file 'run_1.log'

Example
The following example deletes the f_1.txt file.
struct f_str_9 {
FDel(ex_file: string) is {
var my_f_1: string;
my_f_1 = files.add_file_type(ex_file, ".txt", TRUE);
files.file_delete(my_f_1);
};
};
extend sys {
fi_9: f_str_9;
run() is also {
fi_9.FDel("f_1.txt");
};
Specman e Language Reference
1999-2015

1579
.

Product Version 15.1


All Rights Reserved.

};

See Also

file_exists() on page 1580

27.14.5.6 file_exists()
Purpose
Check if a file exists

Category
Method

Syntax
files.file_exists(file-name: string): bool
Syntax Example
var f_e: bool;
f_e = files.file_exists("file_1.e");

Parameter
file-name

The name of the file or directory to be checked.

Description
Check if the file-name exists in the file system. Return TRUE if the file exists, including if the file is a
directory. Returns FALSE if the file does not exist. The routine does not check whether the file is
readable or not.

Note
This routine only checks for the existence of a file with the exact name you specify. For a routine that
can check for multiple similarly named files, see add_file_type() on page 1572.

Specman e Language Reference


1999-2015

1580

Product Version 15.1


All Rights Reserved.

Example
The following example checks whether a file is on the $SPECMAN_PATH, and prints an appropriate
message.
extend sys {
on_specman_path(file: string) is {
var specman_path: string;
specman_path = get_symbol("SPECMAN_PATH");
var specman_dirs: list of string;
specman_dirs = str_split(specman_path, ":");
for each (dir) in specman_dirs {
if dir == "" {
-- An empty directory is actually the current directory.
specman_dirs[index] = ".";
};
};
for each (dir) in specman_dirs {
if files.file_exists(append(dir, "/", file)) {
out(file, " exists on $SPECMAN_PATH in directory ", dir);
return;
};
};
out(file, " does not exist on $SPECMAN_PATH");
};
run() is also {
on_specman_path("foo.txt")
};
};

See Also

add_file_type() on page 1572

file_is_dir() on page 1583

file_is_readable() on page 1586

file_is_regular() on page 1587

file_is_link() on page 1584

file_is_text() on page 1590

Table 2-6 on page 202, for information about type conversion between scalar types

Specman e Language Reference


1999-2015

1581
.

Product Version 15.1


All Rights Reserved.

27.14.5.7 file_extension()
Purpose
Get the extension of a file

Category
Method

Syntax
files.file_extension(file-name: string): string
Syntax Example
var f_ext: string;
f_ext = files.file_extension("f_1.exa");

Parameter
file-name

The name of the file.

Description
Returns a string containing the file extension, which is the sequence of characters after the last period (.).

Example
The following example prints get_ext = .bak.
struct f_str_11 {
FExten(ex_file: string) is {
var get_ext: string;
get_ext = files.file_extension(ex_file);
print get_ext;
};
};
extend sys {
fi_11: f_str_11;
run() is also {
fi_11.FExten("f_1.bak");
};
};
Specman e Language Reference
1999-2015

1582

Product Version 15.1


All Rights Reserved.

See Also

add_file_type() on page 1572

file_exists() on page 1580

Table 2-7 on page 205, for information about type conversion between strings and scalar types

27.14.5.8 file_is_dir()
Purpose
Check if a file is a directory

Category
Method

Syntax
files.file_is_dir(file-name: string): bool
Syntax Example
var is_d: bool;
is_d = files.file_is_dir("a_fil");

Parameter
file-name

The name of the file to be checked.

Description
Returns TRUE if the file exists and is a directory. Returns FALSE if the file does not exist or is not a
directory.

Example
The following example prints TRUE if f_1 is a directory, or FALSE if f_1 does not exist or if it is not a
directory.
struct f_str_12 {
F_is_Dir(ex_file: string) is {
var is_dir: bool;
Specman e Language Reference
1999-2015

1583
.

Product Version 15.1


All Rights Reserved.

is_dir = files.file_is_dir(ex_file);
outf("%s is_dir = %s\n", ex_file, is_dir);
};
};
extend sys {
fi_12: f_str_12;
run() is also {
fi_12.F_is_Dir("f_1");
};
};

See Also

file_exists() on page 1580

file_is_link() on page 1584

file_is_readable() on page 1586)

file_is_regular() on page 1587

file_is_temp() on page 1588

file_is_text() on page 1590

Table 2-6 on page 202, for information about type conversion between scalar types

Table 2-7 on page 205, for information about type conversion between strings and scalar types

27.14.5.9 file_is_link()
Purpose
Check if a file is a symbolic link

Category
Method

Syntax
files.file_is_link(file-name: string): bool
Syntax Example
var is_l: bool;
is_l = files.file_is_link("a_fil");

Specman e Language Reference


1999-2015

1584

Product Version 15.1


All Rights Reserved.

Parameter
file-name

The name of the file to be checked.

Description
Returns TRUE if the file exists and is a symbolic link. Returns FALSE if the file does not exist or is not
a symbolic link.

Example
The following example prints TRUE if f_1 is a symbolic link, or FALSE if f_1 does not exist or if it is
not a symbolic link.
struct f_str_13 {
F_is_Link(ex_file: string) is {
var is_link: bool;
is_link = files.file_is_link(ex_file);
outf("%s is_link = %s\n", ex_file, is_link);
};
};
extend sys {
fi_13: f_str_13;
run() is also {
fi_13.F_is_Link("f_1");
};
};

See Also

file_exists() on page 1580

file_is_dir() on page 1583

file_is_readable() on page 1586)

file_is_regular() on page 1587

file_is_temp() on page 1588

file_is_text() on page 1590

Table 2-6 on page 202, for information about type conversion between scalar types

Specman e Language Reference


1999-2015

1585
.

Product Version 15.1


All Rights Reserved.

27.14.5.10file_is_readable()
Purpose
Check if a file is readable

Category
Method

Syntax
files.file_is_readable(file-name: string): bool
Syntax Example
var is_rd: bool;
is_rd = files.file_is_readable("a_fil");

Parameter
file-name

The name of the file to be checked.

Description
Returns TRUE if the file exists and is readable. Returns FALSE if the file does not exist or is not
readable.

Example
The following example prints TRUE if f_1.dat is readable, or FALSE if f_1.dat does not exist or if it is
not readable.
struct f_str_14 {
F_is_Readable(ex_file: string) is {
var is_readable: bool;
is_readable = files.file_is_readable(ex_file);
outf("%s is_readable = %s\n", ex_file, is_readable);
};
};
extend sys {
fi_14: f_str_14;
run() is also {
fi_14.F_is_Readable("f_1.dat");
Specman e Language Reference
1999-2015

1586

Product Version 15.1


All Rights Reserved.

};
};

See Also

file_exists() on page 1580

file_is_dir() on page 1583

file_is_link() on page 1584)

file_is_regular() on page 1587

file_is_temp() on page 1588

file_is_text() on page 1590

Table 2-6 on page 202, for information about type conversion between scalar types

27.14.5.11file_is_regular()
Purpose
Check if a file is a regular file (not a directory or link)

Category
Method

Syntax
files.file_is_regular(file-name: string): bool
Syntax Example
var is_rg: bool;
is_rg = files.file_is_regular("a_fil");

Parameter
file-name

The name of the file to be checked.

Description
Returns TRUE if the file exists and is a regular file. Returns FALSE if the file does not exist or if it is a
directory or a symbolic link.
Specman e Language Reference
1999-2015

1587
.

Product Version 15.1


All Rights Reserved.

Example
The following example prints TRUE if f_1 is a regular file, or FALSE if f_1 does not exist or if it is a
link or directory.
struct f_str_15 {
F_is_Regular(ex_file: string) is {
var is_regular: bool;
is_regular = files.file_is_regular(ex_file);
outf("%s is_regular = %s\n", ex_file, is_regular);
};
};
extend sys {
fi_15: f_str_15;
run() is also {
fi_15.F_is_Regular("f_1");
};
};

See Also

file_exists() on page 1580

file_is_dir() on page 1583

file_is_link() on page 1584

file_is_readable() on page 1586)

file_is_temp() on page 1588

file_is_text() on page 1590

Table 2-6 on page 202, for information about type conversion between scalar types

27.14.5.12file_is_temp()
Purpose
Check if a file name starts with /tmp

Category
Method

Specman e Language Reference


1999-2015

1588

Product Version 15.1


All Rights Reserved.

Syntax
files.file_is_temp(file-name: string): bool
Syntax Example
var is_tmp: bool;
is_tmp = files.file_is_temp("a_fil");

Parameter
file-name

The name of the file to be checked.

Description
Returns TRUE if the file name starts with /tmp, otherwise returns FALSE.

Example
The following example prints /tmp/f_1.dat is_temp = TRUE.
struct f_str_16 {
F_is_Temp(ex_file: string) is {
var is_temp: bool;
is_temp = files.file_is_temp(ex_file);
outf("%s is_temp = %s\n", ex_file, is_temp);
};
};
extend sys {
fi_16: f_str_16;
run() is also {
fi_16.F_is_Temp("/tmp/f_1.dat");
};
};

See Also

new_temp_file() on page 1596

file_exists() on page 1580

file_is_dir() on page 1583

file_is_link() on page 1584

file_is_readable() on page 1586)

file_is_regular() on page 1587

Specman e Language Reference


1999-2015

1589
.

Product Version 15.1


All Rights Reserved.

file_is_text() on page 1590

Table 2-6 on page 202, for information about type conversion between scalar types

27.14.5.13file_is_text()
Purpose
Check if a file is a text file

Category
Method

Syntax
files.file_is_text(file-name: string): bool
Syntax Example
var is_txt: bool;
is_txt = files.file_is_text("a_fil");

Parameter
file-name

The name of the file to be checked.

Description
Returns TRUE if the file is a text file (that is, if it contains more than 20% printable characters). Returns
FALSE if the file does not exist or if it is a not a text file.

Example
The following example prints TRUE if f_1.dat is a text file, or FALSE if f_1.dat does not exist or if it is
not a text file.
struct f_str_17 {
F_is_Text(ex_file: string) is {
var is_text: bool;
is_text = files.file_is_text(ex_file);
outf("%s is_text = %s\n", ex_file, is_text);
};

Specman e Language Reference


1999-2015

1590

Product Version 15.1


All Rights Reserved.

};
extend sys {
fi_17: f_str_17;
run() is also {
fi_17.F_is_Text("f_1.dat");
};
};

See Also

file_exists() on page 1580

file_is_dir() on page 1583

file_is_link() on page 1584

file_is_readable() on page 1586)

file_is_regular() on page 1587

file_is_temp() on page 1588

Table 2-6 on page 202, for information about type conversion between scalar types

27.14.5.14file_rename()
Purpose
Rename a file

Category
Method

Syntax
files.file_rename(from-file-name: string, to-file-name: string)
Syntax Example
files.file_rename("f_1.exa", "b_1.exa");

Parameters
from-file-name

The file to rename.

to-file-name

The new file name.

Specman e Language Reference


1999-2015

1591
.

Product Version 15.1


All Rights Reserved.

Description
Renames the file named from-file-name to to-file-name. If any files already exists with to-file-name, that
file is overwritten by the contents of the file named from-file-name.
If the file or directory is not writable, an error is issued.

Example
The following example changes the name of the f_1.dat file to f_old.dat. If the f_1.dat file does not exist,
the files.add_file_type() routine issues an error.
struct f_str_18 {
FRename(ex_file_1: string, ex_file_2:string) is {
var m_f: string;
m_f = files.add_file_type(ex_file_1, "", TRUE);
files.file_rename (m_f, ex_file_2);
};
};
extend sys {
fi_18: f_str_18;
run() is also {
fi_18.FRename("f_1.dat", "f_old.dat");
};
};

See Also

add_file_type() on page 1572

file_copy() on page 1577

27.14.5.15file_size()
Purpose
Get the size of a file

Category
Method

Specman e Language Reference


1999-2015

1592

Product Version 15.1


All Rights Reserved.

Syntax
files.file_size(file-name: string): int
Syntax Example
var f_s: int;
f_s = files.file_size("a_file.txt");

Parameter
file-name

The name of the file.

Description
Returns the integer number of bytes in the file. If the file does not exist, an error is issued.

Example
The following example gets and displays the number of bytes in the file named f_1.dat.
struct f_str_19 {
FGetSize(ex_file: string) is {
var m_f: string;
m_f = files.add_file_type(ex_file, "", TRUE);
var f_size: int;
f_size = files.file_size (m_f);
outf("%s size is %d\n", m_f, f_size);
};
};
extend sys {
fi_19: f_str_19;
run() is also {
fi_19.FGetSize("f_1.dat");
};
};

See Also

add_file_type() on page 1572

file_age() on page 1574

Specman e Language Reference


1999-2015

1593
.

Product Version 15.1


All Rights Reserved.

27.14.5.16flush_log_file()
Purpose
Flush log file

Category
Method

Syntax
files.flush_log_file(
file_name: string)
Syntax Example
files.flush_log_file("my_log_file.elog");

Parameter
file_name

Name of an existing file to flush.

Description
This method looks for an existing log file by the given name, and flushes that file to the disk, much like
the file.flush() method. If no such log file exists, nothing is done.
The log file may have been created in different ways. For example, it can be a message file, previously
set with message_manager.set_file_messages() or with a set message file=... command. Or it can be a
notifications file, set with a set notify log_file=... command.
This functionality is useful when the user needs to examine the contents of a log file in the middle of a
run. For example, the run may be stopped on a break point, and the user may need to analyze messages
issued up to that point. In such a case, it might be useful to call the method directly from the prompt
rather than adding it to the code.

See Also

set message -file in the Specman Command Reference

set_file_messages | set_file_messages_off on page 971

set notify -log_file in the Specman Command Reference

Specman e Language Reference


1999-2015

1594

Product Version 15.1


All Rights Reserved.

27.14.5.17get_text_lines()
Purpose
Read lines from a text file

Category
Method

Syntax
files.get_text_lines(file-name: string, first: int, last: int): list of string
Syntax Example
var lines: list of string;
lines = files.get_text_lines("file.txt", 10, 100);

Parameter
file-name

The name of the file to read from.

first

The line number of the first line to read. Must be a positive integer.

last

The line number of the last line to read. Must be a positive integer.

Description
Reads lines from a text file from first line specified until the last line specified and returns the lines as a
list of string after removing the final \n (the final new line character, CR).
The file can be compressed, in which case Specman decompresses the file before retrieving the lines.
This method is more efficient than using the for each line in file action.
File line numbers start from 1:

If last is less than first or first is greater than the number of lines in the file, then an empty list is
returned.
If last is greater than the number of lines in the file, then the method returns the lines from the first
line until the end of the file.

Specman e Language Reference


1999-2015

1595
.

Product Version 15.1


All Rights Reserved.

Example
Assume that the following code is in a file named get_text_lines.e:
extend sys {
run() is also {
out(files.get_text_lines("get_text_lines.e", 3, 5));
};
};

When you run this file, it prints the following:


run() is also {
out(files.get_text_lines("get_text_lines.e", 3, 5));
};

See Also

for each line in file on page 581

write_string_list() / write_compressed_string_list() on page 1597

27.14.5.18new_temp_file()
Purpose
Create a unique temporary file name

Category
Method

Syntax
files.new_temp_file(): string
Syntax Example
var t_name: string;
t_name = files.new_temp_file()

Description
Computes a file name. Each file name this routine produces contains the name of the Specman process,
so names are unique across processes. Returns a string with a period at the end.
Specman e Language Reference
1999-2015

1596

Product Version 15.1


All Rights Reserved.

If the $SPECMAN_TEMP_DIR environment variable has been set, it is used as the prefix of the
directory path in which the file is located. If it has not been defined, the /tmp/specman directory is used
instead.
This routine only creates a file name. To create a file with this name, use the files.open() routine.

Example
The example below creates two file names with a prefixed /tmp/specman directory and prints them.
struct f_str_20 {
FMkTmp() is {
var t_name_1: string;
t_name_1 = files.new_temp_file();
print t_name_1;
var t_name_2: string;
t_name_2 = files.new_temp_file();
print t_name_2;
};
};
extend sys {
fi_20: f_str_20;
run() is also {
fi_20.FMkTmp();
};
};

The example above prints the following.


t_name_1 = "/tmp/specman/sn.<host>.<process-id>/snt_5924_12698."
t_name_2 = "/tmp/specman/sn.<host>.<process-id>/snt_5924_12699."

See Also

file_is_temp() on page 1588

open() on page 1561

Table 2-7 on page 205, for information about type conversion between strings and scalar types

27.14.5.19write_string_list() / write_compressed_string_list()
Purpose
Write a list of strings to a file

Specman e Language Reference


1999-2015

1597
.

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
files.write_string_list(file-name: string, strings: list of string)
files.write_compressed_string_list(file-name: string, strings: list of string)
Syntax Example
var s_list:= {"a string"; "another string"};
files.write_string_list("a_file.txt", s_list);
files.write_compressed_string_list("a_file.txt", s_list);

Parameters
file-name

The file name to write into.

strings

A list of strings to write to the file.

Description
Writes a list of strings into a file. Every string is written on a separate line in the file, with \n appended
to the end of the string. If the file already exists, it is overwritten.
Using write_compressed_string_list() creates a compressed file, which usually takes up less disk space
but cannot be read as a plain text file.
If the list of strings contains a NULL, an error is issued.

Example
The following example writes three lines of text into a file named f_1.txt.
struct f_str_21 {
FWrStr(ex_file: string, str_list: list of string) is {
var m_f: string;
m_f = files.add_file_type(ex_file, "", TRUE);
files.write_string_list(ex_file, str_list);
};
};
extend sys {
fi_21: f_str_21;
Specman e Language Reference
1999-2015

1598

Product Version 15.1


All Rights Reserved.

run() is also {
var fname:string;
fname = "f_1.txt";
var strlist: list of string;
strlist = {"first line"; "second line"; "third line"};
fi_21.FWrStr(fname, strlist);
};
};

See Also

open() on page 1561

write() on page 1568

write_lob() on page 1569

write_ascii_struct() on page 1603

write_binary_struct() on page 1606

27.14.6 Reading and Writing Structs


Structs in e can be read from files and written to files in either binary or ASCII format.
The routines that read structs from files and write structs to files are listed below and described in this
section.

read_ascii_struct() on page 1599

read_binary_struct() on page 1601

write_ascii_struct() on page 1603

write_binary_struct() on page 1606

See Also

File Routines on page 1555

General File Routines on page 1571

Low-Level File Routines on page 1556

27.14.6.1 read_ascii_struct()
Purpose
Read ASCII file data into a struct
Specman e Language Reference
1999-2015

1599
.

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
files.read_ascii_struct(file-name: string, struct: struct-type): struct
Syntax Example
var a_str: s_struct;
a_str = files.read_ascii_struct("a_s.out",
"s_struct").as_a(s_struct);

Parameters
file-name

The name of the file to read from. The file may have been created either with
files.write_ascii_struct() or in a similar format with an editor.

struct

The struct type to read data into.

Description
Reads the ASCII contents of file-name into a struct of type struct, and returns a struct. The struct being
read must be cast to the correct data type (see as_a() on page 194). If the file does not exist, an error is
issued.

Example
The following example creates a variable named str to hold an instance of the s_st struct type, reads
ASCII contents of a file named a_s.out into the struct variable, and prints the contents.
struct s_st {
len: int;
hdr: string;
b_l: list of bool;
};
struct r_st {
r_file() is {
var str: s_st;
str = files.read_ascii_struct("a_s.out",
"s_st").as_a(s_st);
print str;
};
run() is also {
Specman e Language Reference
1999-2015

1600

Product Version 15.1


All Rights Reserved.

r_file();
};
};
extend sys {
ri: r_st;
};

See Also

read() on page 1563

read_lob() on page 1564

file_is_readable() on page 1586

read_binary_struct() on page 1601

write_ascii_struct() on page 1603

27.14.6.2 read_binary_struct()
Purpose
Read the contents of a binary file into a struct

Category
Method

Syntax
files.read_binary_struct(file-name: string, struct: struct-type,
check-version: bool): struct
Syntax Example
var b_str: s_struct;
b_str = files.read_binary_struct("b.out", "s_struct",
TRUE).as_a(s_struct);

Parameters
file-name

The name of the file to read from. The file must have been created by
write_binary_struct() on page 1606.

Specman e Language Reference


1999-2015

1601
.

Product Version 15.1


All Rights Reserved.

struct

The struct type to read data into.

check-version

Set to TRUE to compare the contents of the file being read with the definition of
the struct in the currently running module. Set to FALSE to allow minor changes.

Description
Reads the binary contents of file-name into a struct of the specified type, and returns a struct. The struct
being read must be cast to the correct data type (see as_a() on page 194).
If check-version is FALSE, the routine can run even if the order of fields in the file struct is different
from the order of fields in the currently running e module. If check-version is TRUE, an error is issued
if the struct definition has been changed in any way since the struct was written to the file.

Example
The following example creates a variable named str to hold an instance of the s_st struct type, reads
binary contents of a file named b_s.out into the struct variable, and prints the contents. The
check-version parameter is set to TRUE to issue an error if the b_s.out file struct does not exactly match
the s_st definition. The b_s.out binary struct file was created previously by write_binary_struct() on
page 1606.
struct s_st {
len: int;
hdr: string;
b_l: list of bool;
};
struct r_st {
r_file() is {
var str: s_st;
str = files.read_binary_struct("b_s.out", "s_st",
TRUE).as_a(s_st);
print str;
};
run() is also {
r_file();
};
};
extend sys {
ri: r_st;
};

See Also

read() on page 1563

Specman e Language Reference


1999-2015

1602

Product Version 15.1


All Rights Reserved.

read_lob() on page 1564

file_is_readable() on page 1586

read_ascii_struct() on page 1599

write_ascii_struct() on page 1603

27.14.6.3 write_ascii_struct()
Purpose
Write the contents of a struct to a file in ASCII format

Category
Method

Syntax
files.write_ascii_struct(file-name: string, struct: struct, comment: string,
indent: bool, depth: int, max-list-items: int)
Syntax Example
files.write_ascii_struct("a_file.dat", a_str, "my_struct",
TRUE, 2, 10);

Parameters
file-name

The name of the file to write into. If you do not specify a file name extension, the
default extension is .erd, which stands for e-readable data.

struct

The name of the struct instance to write to the file.

comment

A string for a comment at the beginning of the file.

indent

Boolean selector for indentation to the structs field depth.

depth

The number of levels of nested structs to write.

max-list-items

For lists, how many items from each list to write.

Specman e Language Reference


1999-2015

1603
.

Product Version 15.1


All Rights Reserved.

Description
Recursively writes the contents of the struct to the file-name in ASCII format. If the struct contains other
structs, those structs are also written to the file. If the number of hierarchical levels contained in the
struct is greater than the specified depth, levels below the depth level are represented by ellipses (...) in
the ASCII file.
If the file already exists, it is overwritten.
This routine will not write any Specman internal structs. It will write the sys struct, but not any
predefined structs within sys.
The .erd default file name extension is automatically added to the file name only if the file name you
specify has no extension and does not end with . (a period). That is, if you enter myfile, the file
name becomes myfile.erd. If you enter myfile., the file is named myfile.. If you enter
myfile.out, the file is named myfile.out.

Example
In the following example, there are three levels of hierarchy under the sys struct: the w_st struct contains
a s_st struct, which contains a list of dat_s structs. The ss_i instance of the s_st struct is written to an
ASCII file with these options:

The comment My ASCII struct is placed at the top of the file.


Indentation of the structs fields is TRUE.

Only the highest hierarchical level of structs is written (depth = 1).

The first three items in lists are written.


struct dat_s {
dat_l: list of uint;
keep dat_l.size() == 5;
};
struct s_st {
ds_l: list of dat_s;
keep ds_l.size() == 6;
len: int;
hdr: string;
b_l: list of bool;
};
struct w_st {
ss_i: s_st;
wr_file() is {
files.write_ascii_struct("a_s.out", ss_i,
"My ASCII struct", TRUE, 1, 3);
};
run() is also {

Specman e Language Reference


1999-2015

1604

Product Version 15.1


All Rights Reserved.

wr_file();
};
};
extend sys {
wi: w_st;
};

The following is the a_s.out file created by the example above.


-- My ASCII struct
-- The top struct
struct: s_st-@0{
ds_l:
-- struct: ...
-- struct: ...
-- struct: ...
-- ds_l[3..5] ...
};
len: -2025306869
hdr: ""
b_l:
FALSE
TRUE
FALSE
-- b_l[3..3] ...
};
};

Changing depth from 1 to 2 in the example above adds a level of hierarchy to the results, which produces
the following file.
-- My ASCII struct
-- The top struct
struct: s_st-@0{
ds_l:
-- ds_l[0]
struct: dat_s-@1{
-- root___unit: ...
dat_l:
4166871515
381462224
2293917550
-- dat_l[3..4] ...
};
};
-- ds_l[1]
struct: dat_s-@2{
-- root___unit: ...
Specman e Language Reference
1999-2015

1605
.

Product Version 15.1


All Rights Reserved.

dat_l:
3680934570
495418143
1152908095
-- dat_l[3..4] ...
};
};
-- ds_l[2]
struct: dat_s-@3{
-- root___unit: ...
dat_l:
1924257378
1889370393
3534009340
-- dat_l[3..4] ...
};
};
-- ds_l[3..5] ...
};
len: -2025306869
hdr: ""
b_l:
FALSE
TRUE
FALSE
-- b_l[3..3] ...
};
};

See Also

write() on page 1568

write_lob() on page 1569

read_ascii_struct() on page 1599

write_binary_struct() on page 1606

27.14.6.4 write_binary_struct()
Purpose
Write the contents of a struct to a file in binary format

Specman e Language Reference


1999-2015

1606

Product Version 15.1


All Rights Reserved.

Category
Method

Syntax
files.write_binary_struct(file-name: string, struct: struct)
Syntax Example
files.write_binary_struct("b_file.dat", b_str);

Parameters
file-name

The name of the file to write structs into.

struct

The name of the struct instance to write to the file.

Description
Recursively writes the contents of the struct to the file-name in binary format. If the struct contains other
structs, those structs are also written to the file. If the file already exists, it is overwritten.

Example
The following example creates a struct instance named str and writes the structs contents in binary
format to a file named b_s.out.
struct s_st {
len: int;
hdr: string;
b_l: list of bool;
};
struct w_st {
wr_file() is {
var str := a new s_st with {
.len = 1;
.hdr = "top";
.b_l = { TRUE; FALSE; TRUE };
};
files.write_binary_struct("b_s.out", str);
};
run() is also {
wr_file();
};
};
Specman e Language Reference
1999-2015

1607
.

Product Version 15.1


All Rights Reserved.

extend sys {
wi: w_st;
};

See Also

write() on page 1568

write_lob() on page 1569

read_binary_struct() on page 1601

write_ascii_struct() on page 1603

27.15 On-the-Fly Garbage Collection Routine


27.15.1 do_otf_gc()
Purpose
Perform on-the-fly garbage collection

Category
Routine

Syntax
do_otf_gc()
Syntax Example
do_otf_gc();

Description
This routine performs on-the-fly garbage collection. It can be called at any time from either a regular
method or a TCM. It takes no arguments and returns no value.
Use this routine at any point when reducing the Specman memory heap would be beneficial. For
example, use this routine between Specman ticks, when significant memory can accumulate. (Regular
garbage collection does not occur between ticks.)

Specman e Language Reference


1999-2015

1608

Product Version 15.1


All Rights Reserved.

Notes

The do_otf_gc() routine is not related to the regular garbage collection mechanism, although keeping
the memory heap low with do_otf_gc() helps limit the amount of regular garbage collection that is
performed.

The do_otf_gc() routine does consume some CPU time, so it should be used in moderation.

Use the print_otf_msg configuration option to request that on-the-fly GC messages be printed.

Example
This example calls do_otf_gc() from a TCM. However, it can also be called from a regular method.
unit port {
drive_frames
: out buffer_port of frame is instance;
keep drive_frames.buffer_size() == 200;
num_frames: uint;
!next_frame: frame;
in_frames() @sys.any is {
var in_count : uint ;
while (in_count < num_frames) {
gen next_frame;
drive_frames.put(next_frame);
in_count += 1;
// invoke on-the-fly garbage collection every 10 frames
if (in_count % 10 == 0) then {
do_otf_gc();
};
};
};
};

See Also

Managing Specman Memory in the Specman Performance Handbook

configure memory in the Specman Command Reference

set_config() on page 1530

Specman e Language Reference


1999-2015

1609
.

Product Version 15.1


All Rights Reserved.

27.16 Calling Predefined Routines


27.16.1 routine()
Purpose
Call a predefined routine

Category
Action

Syntax
routine-name()
routine-name(param, ...)
Syntax Example
var s := str_join(slist," - ");

Parameters
routine-name

The name of the routine.

param

One or more parameters separated by commas, one parameter for each parameter
in the parameter list of the routine definition. Parameters are passed by their
relative position in the list, so the name of the parameter being passed does not
have to match the name of the parameter in the routine definition. The
parentheses around the parameter list are required even if the parameter list is
empty.

Description
Calls a predefined routine passing it the specified parameters.

Example
This example shows how to call a predefined routine.
<'
Specman e Language Reference
1999-2015

1610

Product Version 15.1


All Rights Reserved.

extend sys {
m1() is {
var slist: list of string = {"first";"second";"third"};
var s := str_join(slist," - ");
print s;
};
};
'>

Result
Specman > sys.m1()
s = "first - second - third"

Specman e Language Reference


1999-2015

1611
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

1612

Product Version 15.1


All Rights Reserved.

28

Modeling State Machines

This chapter contains descriptions of how to create state machines and of the constructs used in them. It
contains the following sections.

State Machine Overview on page 1613

State Machine Constructs on page 1614

Sample State Machine on page 1620

Using State Machines on page 1621

See Also

Invoking Methods on page 535

e Data Types on page 137

28.1 State Machine Overview


The e language state machine action provides constructs for modeling state machines in Specman.
A state machine definition consists of the state machine action followed by a state holder expression
and a block that specifies the ways the state machine can get from one state to another (see state
machine on page 1614).
State machines can be defined only within time-consuming methods (TCMs). When the execution of a
TCM reaches a state machine action, the appropriate series of state transitions occurs, and then the state
machine exits. At this point the TCM continues from the action following the state machine action.

See Also

State Machine Constructs on page 1614

Specman e Language Reference


1999-2015

1613
.

Product Version 15.1


All Rights Reserved.

Sample State Machine on page 1620

Using State Machines on page 1621

28.2 State Machine Constructs


The e state machine constructs are used to define state machines and the transitions between their states.
This section contains descriptions of the following constructs.

state machine on page 1614

state => state on page 1617

* => state on page 1618

state action on page 1619

28.2.1

state machine

Purpose
Define a state machine

Category
Action

Syntax
state machine state-holder-exp [until final-state]
{(state-transition | state) {action; ...}; ...}
Syntax Example
!c_proc: [st, dn];
s_m()@sys.clk is {
state machine c_proc until dn {
*=> st {wait rise('top.rst'); wait [2]*cycle};
st => dn {out("going to dn"); wait [3]*cycle;};
};
};

Specman e Language Reference


1999-2015

1614

Product Version 15.1


All Rights Reserved.

Parameters
state-holder-exp

Stores the current state of the state machine. This can be a variable in the current
TCM, a field under sys, or any assignable expression. It typically is an
enumerated type field of the struct in which the TCM is defined.

final-state

The state at which the state machine terminates.

state-transition

A state transition, which occurs when the associated action block finishes. See
state => state on page 1617 and * => state on page 1618.

state

A state. When this state is entered, the associated action block is invoked. See
state action on page 1619.

action; ...

One of the following:

An action block which, upon completion, causes the transition to occur, if


the state-transition syntax is used.
An action block that is to be performed when the given state is entered, if the
state syntax is used.

Description
Defines a state machine using an enumerated state-holder-exp to hold the current state of the machine.
The state machine must be defined in a time-consuming method (TCM). When the state machine action
is reached, the state machine starts, in the first state listed in the enumerated state holder expression type
definition.
During the execution of the state machine action the current state is stored in the state-holder-exp.
If the optional until final-state exit condition is used, the state machine runs until that state is reached.
The final state must be one of the enumerated values declared with the state machine name.
If the until clause is not used, the state machine runs until the TCM is terminated, or, if the state machine
is in an all of or first of action, it runs until the all of or first of action completes (see Terminating a
State Machine on page 1622).
The state-transition block is a list of the allowed transitions between states of the state machine. Each
state transition contains an action block that defines conditions that cause the transition to occur.
Typically, the action block contains a single wait until action. However, it can contain any block of
actions. For example,
x => y {wait until @named_event_1; wait until @named_event_2};

The transition only occurs after both events happen, in order.

Specman e Language Reference


1999-2015

1615
.

Product Version 15.1


All Rights Reserved.

The action block can contain a regular method, as in the following.


x => y {wait until change(p_clk); me.packet.bb_operations()};

Once change(p_clk) happens, the method executes immediately, and then the transition occurs.

Example
In the following example, the struct field expression used for the state machine is the status field
declaration. The state machine name is status, and its possible states are start and done. The state
machine is defined in the sm_meth() TCM. It has a final state of done, meaning the state machine
terminates when it enters the done state.
Since the start field is listed first in the list of states, that is the initial state for the state machine. The
state changes from start to done two sys.smclk cycles after it enters the start state. Upon
entering the done state, the state machine exits. The out() action is executed after the state machine
exits.
struct smp_state_machine{
!status: [start, done];
sm_meth() @sys.smclk is {
state machine status until done {
start => done {wait [2]*cycle};
};
out("The status state machine is done");
};
};

A more complex state machine is shown below. The name of the state machine is arbiter_state, and it
is declared with states idle, busy, grant, and reject.
This state machine has no until finish-state exit condition, so it runs until it the watcher() TCM is
terminated.
The * => idle syntax means from any other state to the idle state. The condition for this transition is
that 10 cycles of sys.pclk have elapsed since the state machine entered the any state.
struct bus {
!arbiter_state: [idle, busy, grant, reject];
watcher() @sys.pclk is {
wait [3]*cycle;
state machine arbiter_state {
idle => busy {wait @sys.req};
busy => grant {wait [2]*cycle};
busy => reject {wait @sys.bad_pkt};
* => idle {wait [10]*cycle};
};
};
Specman e Language Reference
1999-2015

1616

Product Version 15.1


All Rights Reserved.

};

See Also

State Machine Overview on page 1613

state => state on page 1617

* => state on page 1618

state action on page 1619

28.2.2

state => state

Purpose
One-to-one state transition

Category
State transition

Syntax
current-state=>next-state {action; ...}
Syntax Example
begin => run {wait [2]*cycle; out("Run state entered")};

Parameters
current-state

The state from which the transition starts.

next-state

The state to which the transition changes.

action; ...

The sequence of actions that precede the transition. It usually contains at least one
time-consuming action.

Description
Specifies how a transition occurs from one state to another. The action block starts executing when the
state machine enters the current state. When the action block completes, the transition to the next state
occurs.
Specman e Language Reference
1999-2015

1617
.

Product Version 15.1


All Rights Reserved.

Example
The example below shows a definition of a transition for the initial state to the running state. If the
'top.start' HDL signal changes while the state machine is in the initial state, the state changes to
running.
initial => running {wait until change('top.start')@sim};

See Also

State Machine Overview on page 1613

state machine on page 1614

* => state on page 1618

state action on page 1619

28.2.3

* => state

Purpose
Any-to-one state transition

Category
State transition

Syntax
*=>next-state {action; ...}
Syntax Example
* => pause {wait @sys.restart; out("Entering pause state");};

Parameters
next-state

The state to which the transition changes.

action; ...

The sequence of actions that precede the transition. It usually contains at least one
time-consuming action.

Specman e Language Reference


1999-2015

1618

Product Version 15.1


All Rights Reserved.

Description
Specifies how a transition occurs from any defined state to a particular state. The action block starts
executing when the state machine enters a new state. When the action block completes, the transition to
the next state occurs.

Example
The example below shows a definition of a transition for any state to the running state. From any state,
if the 'top.start' HDL signal rises and later the 'top.hold' signal falls, the state changes to running.
* => running { wait until rise('top.start')@pclk;
wait until fall('top.hold')@pclk };

See Also

State Machine Overview on page 1613

state machine on page 1614

state => state on page 1617

state action on page 1619

28.2.4

state action

Purpose
Execute actions upon entering a state, with no state transition

Category
State action block

Syntax
current-state {action; ...}
Syntax Example
* => run {out("* to run"); wait cycle};
run {out("In run state"); wait cycle; out("Still in run");};
run => done {out("run to done"); wait cycle};

Specman e Language Reference


1999-2015

1619
.

Product Version 15.1


All Rights Reserved.

Parameters
current-state

The state for which the action block is to be executed.

action; ...

The sequence of actions that is executed upon entering the current state. It usually
contains at least one time-consuming action.

Description
Specifies an action block that is executed when a specific state is entered. No transition occurs when the
action block completes. The state machine stays in the current state until some other transition takes
place.

Example
The last two lines in the following example contain an action block that is to be executed when the state
machine enters the running state. The while TRUE ... action means that as long as the state machine
is in the running state, the out() action is executed every cycle.
state machine sm_1 until done {
initial => running { wait until rise('top.a') };
initial => done { wait until change('top.r1');
wait until rise('top.r2') };
running => initial { wait until rise('top.b') };
running {
out("Entered running state");
while TRUE {wait cycle; out("still running");}
};
};

See Also

State Machine Overview on page 1613

state machine on page 1614

state => state on page 1617

* => state on page 1618

28.3 Sample State Machine


The following example shows a single state machine. The state machine is declared in the sm_1 field,
with possible states named initial, running, and done.
struct exa_1_state_machine {
Specman e Language Reference
1999-2015

1620

Product Version 15.1


All Rights Reserved.

!sm_1: [initial, running, done];


tcm_1()@sys.sm_clk is {
wait [10]*cycle;
state machine sm_1 until done {
initial => running { wait until rise('top.a') };
initial => done { wait until change('top.r1');
wait until rise('top.r2') };
running => done {wait until fall('top.b')};
running {while TRUE {out("Running"); wait cycle}};
};
out("tcm_1 finished");
};
};

The sm_1 state machine is defined in the tcm_1() TCM. Note that the TCM contains other actions
besides the state machine. There is a 10-cycle wait before the state machine starts, and an out() that is
executed after the state machine is finished.
The until done clause means that the state machine will run until it reaches the done state.
The transition definitions are as follows:
initial => running

A rise of the 'top.a' HDL signal causes a transition from initial to


running.

initial => done

A change in the 'top.r1' signal followed eventually by a rise in the 'top.r2'


signal causes a transition from initial to done.

running => done

A fall of the 'top.b' signal causes a transition from running to done.

running

When the state machine enters the running state, continuously execute the
{out(Running); wait cycle}; action block until the state changes.

See Also

State Machine Overview on page 1613

State Machine Constructs on page 1614

Using State Machines on page 1621

28.4 Using State Machines


This section contains the following topics.

Initializing a State Machine on page 1622

Terminating a State Machine on page 1622

Rules for State Transitions on page 1624

Specman e Language Reference


1999-2015

1621
.

Product Version 15.1


All Rights Reserved.

Nested State Machines on page 1624

Parallel State Machines on page 1625

28.4.1

Initializing a State Machine

State machines start by default in the first state specified in the enumerated type definition of the
state-holder-exp (see State Machine Overview on page 1613). In the following, the starting state for
state machine sm_2 is initial because that is the first state listed in the sm_2 type definition.
struct exa_2_state_machine{
!sm_2: [initial, running, done];
tcm_2()@sys.sm_clk is {
state machine sm_2 until done {
// ...
};
};
};

If the state machine is entered several times in the same TCM, it is initialized to the starting state each
time it is entered. A state machine can be re-entered if it is nested in another state machine or if it is
enclosed in a loop. Conditional initialization of the state machine can be performed within the state
machine as shown in the following.
struct exa_2_state_machine{
!sm_2: [initial, init_cond, init_no_cond, running, done];
tcm_2()@sys.sm_clk is {
state machine sm_2 until done {
initial => init_cond {sync true(cond);};
initial => init_no_cond {sync true(not cond);};
// ...
};
};
};

See Also

State Machine Overview on page 1613

28.4.2

Terminating a State Machine

You can terminate a state machine in any of the following ways.

Specify a final state in an until clause.

Enclose the state machine within a first of action.

Specman e Language Reference


1999-2015

1622

Product Version 15.1


All Rights Reserved.

Terminate the TCM using the quit() method.

A state machine defined as follows will exit when it reaches the done state. The TCM continues
execution.
struct exa_3_state_machine{
!sm_3: [initial, running, done];
tcm_3()@sys.tclk is {
state machine sm_3 until done {
// ...
};
// ...
};
};

The following state machine is enclosed in a first of action. The other thread of the first of action
terminates after wait [MAXN] * cycle. If the state machine runs for MAXN cycles, the wait thread
finishes and the TCM terminates.
struct exa_4_state_machine {
!sm_4: [initial, running, done];
tcm_4()@sys.tclk is {
first of {
{wait [MAXN]*cycle;};
{state machine sm_4 {
// ...
};
};
// ...
};
};
};

The quit() method of the struct can be used in another TCM to terminate all active TCMs and their state
machines. This method cannot be used to terminate only one of several active TCMs, nor can it
terminate a state machine while allowing the TCM to continue executing. In the following example, a
TCM in sys calls the quit() method of the exa_4_state_machine instance, which terminates the
tcm_4() TCM and the state machine.
struct exa_4_state_machine{
!sm_4: [initial, running, done];
tcm_4()@sys.tclk is {
state machine sm_4 {
// ...
};
};
};

Specman e Language Reference


1999-2015

1623
.

Product Version 15.1


All Rights Reserved.

See Also

State Machine Overview on page 1613

28.4.3

Rules for State Transitions

A transition takes place when its action block finishes.


If there are several contending transitions (for example, several transitions with the same
current-state), their action blocks are executed in parallel. The transition whose action block finishes
first is the one that occurs.
When the action blocks for two transitions can complete during the same cycle, it is not possible to
determine which transition will prevail. One will occur successfully and the other will not occur.
Action blocks can take time, but transitions themselves take no time.

If the state machine specifies:


x => y {sync true('cpu.clock' == 1)};
y => z {sync true('alu.clock' == 1)};

and both cpu.clock and alu.clock are high within the same cycle, the two transitions both occur
within the same cycle.

See Also

State Machine Overview on page 1613

28.4.4

Nested State Machines

A state machine is just an action like all others, so it can appear anywhere an action can appear. This
makes nested and parallel state machines possible. For example, the following contains a state machine
named run_to_finish nested within another state machine named sm_5.
struct exa_5_state_machine {
!sm_5: [begin, run, finish];
run_to_finish: [s_b1, s_b2, s_b3];
tcm_5() @sys.pclk is {
state machine sm_5 until finish {
begin => run {wait [2]*cycle};
run => finish {
state machine run_to_finish until s_b3 {
s_b1 => s_b2 {wait [2]*cycle};
s_b2 => s_b1 {wait [3]*cycle};
s_b2 => s_b3 {wait @sys.s_reset};
};
Specman e Language Reference
1999-2015

1624

Product Version 15.1


All Rights Reserved.

};
* => begin {wait @sys.reset};
};
};
};

Whenever the sm_5 state machine enters the run state, it starts the nested run_to_finish state
machine. When that machine finally reaches its s_b3 state it exits, and the sm_5 state machine
enters its finish state.
If sys.reset becomes TRUE, the sm_5 state machine enters its begin state regardless of the current
state of the run_to_finish state machine. This is an example of preempting a state machine from the
outside.

See Also

State Machine Overview on page 1613

28.4.5

Parallel State Machines

An example of parallel state machines is shown below.


struct exa_6_state_machine {
!sm_6a: [x1, x2, x3];
!sm_6b: [y1, y2];
tcm_6() @sys.sclk is {
all of {
state machine sm_6a until x3 {
// ...
};
state machine sm_6b until y2 {
// ...
};
};
out("sm_6a and sm_6b state machines are both done");
};
};

The two state machines in the example above are entered at the same time, and each proceeds
independently of the other. Because they are started in an all of construct, both state machines must exit
before the out() action can be executed.
In the following example, the two state machines are started in a first of rather than all of construct.
struct exa_6_2_state_machine {
!sm_6a_2: [x1, x2, x3];
!sm_6b_2: [y1, y2];
Specman e Language Reference
1999-2015

1625
.

Product Version 15.1


All Rights Reserved.

tcm_6_2() @sys.sclk is {
first of {
state machine sm_6a_2 until x3 {
// ...
};
state machine sm_6b_2 until y2 {
//...
};
};
out("either sm_6a_2 or sm_6b_2 state machine is done");
};
};

Parallel state machines can be nested within another state machine, as in the following.
a => b {
all of {
state machine x until end_x {. . .};
state machine y until end_y {. . .};
};
};

See Also

State Machine Overview on page 1613

Specman e Language Reference


1999-2015

1626

Product Version 15.1


All Rights Reserved.

29

Encapsulation Constructs

This chapter contains syntax and descriptions of the e statements that are used to create packages and
modify access control. The constructs are:

package package-name on page 1627

package type-declaration on page 1628

package | protected | private struct-member on page 1630

Scope Operator on page 1632

Note

See also the description of const in field on page 225.

29.1 package package-name


Purpose
Associates a module with a package.

Category
Statement

Syntax
package package-name
Syntax Example
package vr_xb;

Specman e Language Reference


1999-2015

1627
.

Product Version 15.1


All Rights Reserved.

Parameters
package- name

A standard e identifier which assigns a unique name to the package. It is


legal for a package name to be the same as a module or type name.

Description
Only one package statement can appear in a file, and it must be the first statement in the file.
A file with no package statement is equivalent to a file beginning with the statement, package main.

Example
<'
// module vr_xb_top
package vr_xb;
'>

See Also

package type-declaration on page 1628

package | protected | private struct-member on page 1630

Encapsulation in e in Creating e Testbenches

29.2 package type-declaration


Purpose
Modifies access to a type, struct, or template.

Category
Statement

Syntax
[package] type-declaration
Syntax Example
package type t: int(bits: 16);
Specman e Language Reference
1999-2015

1628

Product Version 15.1


All Rights Reserved.

Parameters
type-declaration An e type declaration for a struct, unit, template, enumerated list, or
other type.

Description
The package modifier means that code outside the package files cannot access the defined type. This
includes declaring a variable of the type or template, extending, inheriting, casting using the as_a
operator, and all other contexts in which the name of a type or template is used. It is equivalent to the
default (package) access level for classes in Java.
Note

The package type does not determine the visibility of a package, but only its access control.

Without the package modifier, there are no access limitations on the declared type.
Definition of a when subtype (using a when or extend clause) does not allow for an access modifier. A
when subtype is public, unless either its base struct or one of its determinant fields is declared package.
A when subtype cannot have a private or protected determinant field. Any reference to a when
subtype, even in a context in which the when determinant field is accessible, results in a compilation
error.
Similarly, a keyed list is public unless either its element type or its key field is declared as a package. A
keyed list cannot have private or protected key field. Reference to such a list results in a compilation
error.

Example
<'
// module vr_xb_top
package vr_xb;
package type width: uint(bits: 8);
'>

See Also

package package-name on page 1627

package | protected | private struct-member on page 1630

Encapsulation in e in Creating e Testbenches

Specman e Language Reference


1999-2015

1629
.

Product Version 15.1


All Rights Reserved.

29.3 package | protected | private struct-member


Purpose
Modifies access to a struct field, method, or event.

Category
Keyword

Syntax
package struct-member-definition
protected struct-member-definition
private struct-member-definition
Syntax examples:
private f: int;
protected m() is {};
package event e;

Parameters
structmemberdefinition

A struct or unit field, method, or event definition. See Structs, Fields and Subtypes in the
Specman e Language Reference for the syntax of struct and unit member definitions.

Description
A struct member declaration may include a package, protected, or private keyword to modify access
to the struct member.
If no access modifier exists in the declaration of a struct member, the struct member has no access
restriction (the default is public).
The package modifier means that code outside the package files cannot access the struct member. It is
equivalent to the default (package) access level for fields and methods in Java.

Specman e Language Reference


1999-2015

1630

Product Version 15.1


All Rights Reserved.

The protected modifier means that code outside the struct family scope cannot access the struct
member. It is similar (although not equivalent) to the protected semantics in other object-oriented
languages.
The private modifier means that only code within both the package and the struct family scope can
access the struct member. This means that code within the extension of the same struct in a different
package is outside its accessibility scope. It is less restrictive than private attribute of other
object-oriented languages in the sense that methods of derived structs or units within the same package
can access a private struct member.
An extension of a struct member can restate the same access modifier as the declaration has, or omit the
modifier altogether. If a different modifier appears, the compiler issues an error.
All references to a struct member outside its accessibility scope result in an error at compile time. Using
an enumerated fields value as a when determinant is considered such a reference, even if the field name
is not explicitly mentioned.
A field must be declared package or private if its type is package.
A method must be declared package or private if its return type or any of its parameter types are
package.
Only fields, methods and events can have access restrictions. There are other named struct members in
e, namely cover groups and named expects, to which access control does not apply - they are completely
public. However, cover groups and expects are defined in terms of fields, methods and events, and can
refer to other entities in their definitions according to the accessibility rules.

Example
<'
package P1;
struct s1 {
private f: int;
protected m() is {};
package event e;
};
'>

See Also

package package-name on page 1627

package type-declaration on page 1628

Encapsulation in e in Creating e Testbenches

Specman e Language Reference


1999-2015

1631
.

Product Version 15.1


All Rights Reserved.

29.4 Scope Operator


29.4.1

::

Purpose
Identify the package scope for the given type or template reference

Category
Special purpose operator

Syntax
package-name :: type-name
Syntax Example
xbus_e_uvc: vr_xbus::env_u;

Parameters
package-name

The name of the package in which the type was declared. The * wildcard is allowed
when entered with a command.
Note If no package is explicitly associated with the type, the type is implicitly
associated with the package main.

type-name

The name of a struct, unit, template, or scalar type. The * wildcard is allowed when
entered with a command.

Description
Qualifies the name for a given struct, unit, template, or scalar type by defining the package to which the
type belongs. Doing so is required when, otherwise, it would be unclear which type is being referenced.
The e compiler evaluates each type reference according to the type scoping rules and sends an error
message if the reference is ambiguous.

Notes

The scope operator does not apply when you declare a new type with a type, struct, template, or
unit statement. The scope is defined by the package in which the declaration occurs.

Specman e Language Reference


1999-2015

1632

Product Version 15.1


All Rights Reserved.

The scope operator does not relate directly to built-in derivatives of a type, such as lists and
size-modified scalars. Rather, it relates to the explicitly declared type that serves as the base for the
derivatives. For example, the qualified name of list of packet would be list of vr_xbus::packet and
not vr_xbus::list of packet. Similarly in the case of when qualifiers, the qualified name for big
corrupt packet would be big corrupt vr_xbus::packet.
Types declared in modules that do not explicitly associate themselves with a package are part of the
namespace of package main.
The names of types declared in the e_core package are reserved. If you define a struct, unit, template,
or scalar type using one of the e_core package type names, you get a compiler error. However, these
names are not reserved keywords. You can use e_core type names as identifiers in any other context
(variable names, method names, and so on). Examples of e_core types are:
int
sys
any_struct.

Example
package vr_xsoc;
type env_name_t: [];
unit env_u {
name: env_name_t;
xbus_e_uvc: vr_xbus::env_u;

// No qualification would result


// in an ambiguity error
xserial_A_e_uvc: vr_serial::env_u;
xserial_B_e_uvc: vr_serial::env_u;
};

See Also

Type Name Resolution Rules in Creating e Testbenches

Qualified Type Names in Commands in Creating e Testbenches

Qualified Type Names and the C Interface in Creating e Testbenches

Qualified Type Names and the Coverage API in Creating e Testbenches

Specman e Language Reference


1999-2015

1633
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

1634

Product Version 15.1


All Rights Reserved.

30

Objection Mechanism

This section explains the objection mechanism in detail. It includes:

objection_kind enum on page 1635

Objection Counter and Objection Total on page 1635

Methods of any_unit on page 1636

For more information, see:

Introduction to Status Coordination in Creating e Testbenches

30.1 objection_kind enum


The predefined enum type objection_kind contains all topics for which the objection mechanism is
needed.
Initially, it contains the single value TEST_DONE:
type objection_kind: [TEST_DONE];

You can extend objection_kind to add other kinds. For example, you can add soft reset as follows:
extend objection_kind: [SOFT_RESET_DONE];

30.2 Objection Counter and Objection Total


For each objection_kind, each unit holds two pieces of information:

Objection counter: The current number of objections in the unit itself, regardless of its subunits. If
there is no objection, the counter is 0.

Specman e Language Reference


1999-2015

1635
.

Product Version 15.1


All Rights Reserved.

Objection total: The total number of objections in the tree that includes both the unit itself and all of
its subunits.

All of the methods of the API (all of them under any_unit) are tightly related to these two pieces of
information. For details on the methods of any_unit, see Methods of any_unit on page 1636.

30.3 Methods of any_unit


Table 30-1 describes the methods of any_unit (each of which gets objection_kind as a parameter).

Table 30-1

Objection Mechanism Methods

Method

Description

raise_objection(kind: objection_kind)

By calling this method, the unit increments by 1 both:

drop_objection(kind: objection_kind)

Its objection counter to objection_kind


The total objection counter of all its parent units

By calling this method, the unit decrements by 1 both:

Its objection counter to objection_kind


The total objection counter of all its parent units

Calling this method when the objection counter is 0 results


in an error.

Specman e Language Reference


1999-2015

1636

Product Version 15.1


All Rights Reserved.

Table 30-1

Objection Mechanism Methods, continued

Method

Description

all_objections_dropped(kind:
objection_kind)

This extensible method is initially empty, except


sys.all_objections_dropped() when the kind is
TEST_DONE (see End-Of-Test Solution in Managing
Resets and End of Test Creating e Testbenches).
This method is called by Specman whenever the objection
total for objection_kind goes down to zero in the current
unit. In other words, whenever the objection status for
objection_kind is changed in some unit (by calling
raise_objection() or drop_objection() on that unit), the
total for that unit changes immediately. If the total becomes
0, all_objections_dropped() gets called on the unit.
After all_objections_dropped() returns, Specman
continues going up the unit tree towards sys, decrementing
the counter (and hence the total) and calling
all_objections_dropped() for any unit in which the total is
zero.
This method is the main workhorse for doing things upon
the change (for example, raising another objection, starting
a TCM that will drop an objection later, and so on).
Note This is the only objection mechanism method that
should be extended by the user.

get_objection_counter(kind:
objection_kind): int

Returns the objection counter for the unit, that is, the
current number of objections to objection_kind in the unit
itself, regardless of its subunits.

get_objection_total(kind:
objection_kind): int

Returns the objection total of the unit, that is, the total
number of objections to objection_kind in the tree that
includes both the unit itself and all of its subunits.

get_objection_list(kind:
objection_kind): list of any_unit

Returns the list of units directly under the unit (not


including it) for which the objection total is not zero.

Specman e Language Reference


1999-2015

1637
.

Product Version 15.1


All Rights Reserved.

Example
Figure 30-1
Unit A

Objection Status Example

Counter : 1
Total
: 8

Unit B

Counter : 5
Total
: 5

Unit C

Counter : 0
Total
: 0

Unit D

Counter : 0
Total
: 2

Unit E

Counter : 1
Total
: 1

Unit F

Counter : 0
Total
: 0

Unit G

Counter : 1
Total
: 1

In the example shown in Figure 30-1, calling get_objection_list() on Unit A returns a list consisting of
Unit B and Unit D. This method is useful if your logic depends on knowing which of the immediate
descendants is responsible for rejecting a proposed status such as stopping the run.
Note In this example, for Unit A, get_objection_list() returns a list of two units, whereas
get_objection_total() returns a count of 8.

Specman e Language Reference


1999-2015

1638

Product Version 15.1


All Rights Reserved.

e Language Errors

This appendix contains the following error descriptions:

ERR_BAD_FORMAT_STRING on page 1640

ERR_CRC_PARAM on page 1641

ERR_IFDEF on page 1642

ERR_ILLEGAL_REF_PARAM on page 1643

ERR_LIST_ASSIGN on page 1644

ERR_LIST_OF_LIST on page 1644

ERR_MISMATCH_PARAM_NUM on page 1645

ERR_MISMATCH_PARAM_TYPE on page 1646

ERR_MORE_THAN_ONE_FILE_MATCHING on page 1647

ERR_NO_FILE_MATCHING on page 1647

ERR_NO_MATCH_FILE on page 1648

ERR_NOT_ASSIGNABLE on page 1649

ERR_NULL_OBJ on page 1649

ERR_PARAM_NUM on page 1650

ERR_RECURSIVE_MATCH_IN_DEFINE on page 1651

ERR_RETURN_VAL on page 1651

ERR_STR_DOLLAR_STR_MATCH on page 1652

ERR_SWAP_SMALLER_BIGGER on page 1653

ERR_TE_NOFUNC on page 1654

ERR_UNPACK_EMPTY_LIST on page 1655

ERR_NAME_USED_TWICE_IN_SCOPE on page 1656

Specman e Language Reference


1999-2015

1639
.

Product Version 15.1


All Rights Reserved.

ERR_VOID_ERR on page 1657

ERR_LIST_OF_LIST on page 1644

ERR_BAD_FORMAT_STRING
Error Type
Semantic

Description
The first parameter of appendf() is the format of the result string.
This format can include the % character followed by one of the following:

numbers: x, d, o, and b

characters: s and, in version 3.2, u

The character defines the parameter type (as in C printf):


x - hexadecimal digit
d - decimal digit
s - any type
b - binary digit
o - octal digit
To use the correct format, see the full table (type help appendf()). Any other character is not allowed.
This error message occurs when an inappropriate character was used after % in the format string.

Example
vpa-tool> print appendf("%y",1)

Typical Error Message


*** Error: unknown convertor: %y, while expected x,d,s,b,o

Solution/Workaround
Either:

Use double %, if you want the % character itself to appear as a string, as follows:

Specman e Language Reference


1999-2015

1640

Product Version 15.1


All Rights Reserved.

appendf("%%y") = "%y"

%s can receive any type of parameter, therefore, if you do not know which character to use you can
effectively use %s:
appendf("%s",123) = "123"

See Also

Format String on page 1528

outf() on page 1526

appendf() on page 1490

ERR_CRC_PARAM
Error Type
General

Description
An illegal parameter was sent to a CRC function.
The CRC functions are CRC_32() or CRC_32_flip() or CRC_8().

Parameters
offset

index number of the starting byte

length

number of bytes to use

offset + length - 1

index of the last byte

The error occurs when offset or offset + length - 1 is beyond the end of the list, or length is bigger
than the available bytes.

Typical Error Message


*** Error: CRC 32 Bad offset: 50 for 1 0 1

Specman e Language Reference


1999-2015

1641
.

Product Version 15.1


All Rights Reserved.

Solution/Workaround
Use break on error and rerun the test. The debugger will stop on the problematic call. Use the up and
down debugger commands to see the parameters and the accompanying list.

See Also

crc_8() on page 1417

crc_32() on page 1419

crc_32_flip() on page 1421

ERR_IFDEF
Error Type
Syntactic

Description
The constructs ifdef, ifndef, and else must start in a new line, with # as a prefix. The error occurs if the
syntax is not as described.

Example
vpa-tool> ifdef XX then {print XX}

Typical Error Message


*** Error: Syntax error in ifdef/ifndef statement (may be missing
#)

Solution/Workaround
Check the following rules:

if[n]def can be used as a statement, struct-member, action, or command.

if[n]def and else must start in a new line.

if[n]def and else must start with #.

Specman e Language Reference


1999-2015

1642

Product Version 15.1


All Rights Reserved.

See Also

#ifdef, #ifndef on page 1127

Chapter 21 Macros

ERR_ILLEGAL_REF_PARAM
Error Type
Semantic

Description
A list item or a list slice was passed by reference as a parameter to a method. List items or list slices
cannot be passed by reference.

Typical Error Message


*** Error: Cannot pass item of a list by reference
At line 18 in /user/myself/bug.e
m(li[0]);

Solution/Workaround
Either:

Change the called method to accept parameter by value.

Substitute the list item for a variable and pass it by reference to the method.

Copy the list slice into a list, and pass the list by reference to the method.

See Also

Parameter Passing in Methods in Creating e Testbenches

Specman e Language Reference


1999-2015

1643
.

Product Version 15.1


All Rights Reserved.

ERR_LIST_ASSIGN
Error Type
Semantic

Description
A list instance was assigned to a list instance of a different type. A list assignment can be made only for
instances of the same type.

Typical Error Message


*** Error: Cannot assign list lb of type list of byte to list
li of type list of int
At line 7 in /user/myself/bug.e
li = lb;

Solution/Workaround
If there is a conversion between element types, you can use the .as_a() syntax, such as, li = lb.as_a(list
of int). Another useful solution is to use pack() to convert between the lists.

See Also

as_a() on page 194

pack() on page 1059

ERR_LIST_OF_LIST
Error Type
Semantic

Description
This error occurs when attempting to define list of lists.

Specman e Language Reference


1999-2015

1644

Product Version 15.1


All Rights Reserved.

Typical Error Message


*** Error: Cannot define a list of lists

Solution/Workaround
You must define a struct that holds the internal list and then a list of that struct. For example:
<'
struct int_list{
my_list:list of int;
};
extend sys {
m() is {
var t:list of int_list;
};
};
'>

See Also

list of on page 231

ERR_MISMATCH_PARAM_NUM
Error Type
Semantic

Description
The numbers of conversion characters do not match the number of the arguments in the formatted string.

Example
print appendf("%x");

Typical Error Message


*** Error: number of parameters (0) doesnt match formatting
string "%x"

Specman e Language Reference


1999-2015

1645
.

Product Version 15.1


All Rights Reserved.

Solution/Workaround
Add missing arguments and/or delete redundant arguments as required.

See Also

Format String on page 1528

outf() on page 1526

appendf() on page 1490

ERR_MISMATCH_PARAM_TYPE
Error Type
Semantic

Description
Conversion character of scalar for non scalar type was attempted on formatted output.

Example
print appendf("%x", sys)

Typical Error Message


*** Error: type mismatch, argument no. 1, expected scalar or
long, actual type is sys

Solution/Workaround
The conversion character or the printed argument must be changed.

See Also

Format String on page 1528

outf() on page 1526

appendf() on page 1490

Specman e Language Reference


1999-2015

1646

Product Version 15.1


All Rights Reserved.

ERR_MORE_THAN_ONE_FILE_MATCHING
Error Type
General

Description
This error occurs when a regular expression was used to import an e file or verilog file, and Specman
finds more than one file name matching that expression.

Example
vpa-tool> load x*

Typical Error Message


*** Error: There is more than one file matching x*

Solution/Workaround
Use a more precise regular expression: it will also be more efficient.

See Also

ERR_NO_FILE_MATCHING on page 1647

String Matching on page 99

ERR_NO_FILE_MATCHING
Error Type
General

Description
This error occurs when a regular expression was used to import an e file or verilog file, and Specman
does not find a file name matching this expression.

Specman e Language Reference


1999-2015

1647
.

Product Version 15.1


All Rights Reserved.

Example
vpa-tool> load xxxxx*

Typical Error Message


*** Error: No files match xxxxx*

Solution/Workaround
Check again the following parameters which effect the file search path:

The current directory

The imported file directory

Specman path

The file name

See Also

ERR_MORE_THAN_ONE_FILE_MATCHING on page 1647

Specman File Search Path in Compiling, Linking, and Running Specman

String Matching on page 99

ERR_NO_MATCH_FILE
Error Type
General

Description
A load or import of a non-existing file was requested. The file could not be found.

Typical Error Message


*** Error: No match for imported file no_such_file.e

Solution/Workaround
Check for a typo. File names are case sensitive: check this too.

Specman e Language Reference


1999-2015

1648

Product Version 15.1


All Rights Reserved.

If the file is located in a different directory (not the working directory), specify the files path (relative or
absolute). You can also use the SPECMAN_PATH environment variable.

See Also

Specman File Search Path in Compiling, Linking, and Running Specman

ERR_NOT_ASSIGNABLE
Error Type
Semantic

Description
This error is issued whenever a non-assignable expression gets assigned. For example: 5 = 3.
Non-assignable expressions are: numbers, field of a list, constant lists, global, me, an enum name,
NULL, FALSE, TRUE.

Typical Error Message


*** Error: Expression 5 is not assignable

Solution/Workaround
Correct the source line.

ERR_NULL_OBJ
Error Type
Semantic

Description
Calling a NULL object method.

Specman e Language Reference


1999-2015

1649
.

Product Version 15.1


All Rights Reserved.

Typical Error Message


*** Error: cannot call method - object is NULL:

Solution/Workaround
Set break on error and rerun the test. Use the up and down debugger commands to locate the NULL
object.

See Also

break on error in the Specman Command Reference

stack in the Specman Command Reference

ERR_PARAM_NUM
Error Type
Semantic

Description
An extension of a method specifies a different number of parameters than the original method definition.

Trouble Shooting
Find the original method definition, and use the same number and type of parameters in the method
extension definition.

Typical Error Message


*** Error: Parameter number of st.foo() differs from previous
definition
At line 9 in /user/myself/bug.e
foo(i: int) is also {

Solution/Workaround
Find the original method definition, and use the same number and type of parameters in the method
extension definition. To find the original method declaration, use the search command.
Specman e Language Reference
1999-2015

1650

Product Version 15.1


All Rights Reserved.

See Also

search in the Specman Command Reference

source in the Specman Command Reference

collect in the Specman Command Reference

ERR_RECURSIVE_MATCH_IN_DEFINE
Error Type
Semantic

Description
The statement define cannot be recursive; the translation text cannot include define.

Example
vpa-tool> define x 3*x

Typical Error Message


*** Error: recursion found in define declaration:
x==>3*x

Solution/Workaround
Do not use define in the translation text.

See Also

#ifdef, #ifndef on page 1127

Chapter 21 Macros

ERR_RETURN_VAL
Error Type
Semantic

Specman e Language Reference


1999-2015

1651
.

Product Version 15.1


All Rights Reserved.

Description
This error occurs when an expression (which returns a value) was used as an action (which has no return
value).

Example
vpa-tool> append(1)

Typical Error Message


*** Error: append(1) is a value-returning <exp>, not an
<action>

Solution/Workaround
There are two ways to avoid this error.

If you want to save the return value, you should use the expression as part of an action. For example:
var return_value:=append(1);

If you do not want to save the return value, you can use the compute action. For example:
compute append(1);

See Also

ERR_VOID_ERR on page 1657

ERR_STR_DOLLAR_STR_MATCH
Error Type
Semantic

Description
Access of a local pseudo-variable $num when the ~ and !~ operators have not been used.

Typical Error Message


In the example below, because the print statement containing the string comparison is never performed,
the print statement referencing the $1 pseudo-variable generates an error.
Specman e Language Reference
1999-2015

1652

Product Version 15.1


All Rights Reserved.

<'
extend sys {
run() is also {
if FALSE then {
print "aa" ~ "a*";
};
print $1;
};
};
'>
*** Error: Cannot do $1 since no str_match was performed earlier
in scope!

Solution/Workaround
Set break on error and rerun the test to locate the problem.
Either remove the problematic line or add the appropriate str_match() before it.

See Also

break on error in the Specman Command Reference

str_match() on page 1505

ERR_SWAP_SMALLER_BIGGER
Error Type
Semantic

Description
This error occurs when illegal parameters were given to the list-of-bit.swap(small: int, large: int)
method. If the small parameter is bigger than the large parameter, this error message appears.

Typical Error Message


*** Error: Big unit 5 should be to the right of small unit 2.

Specman e Language Reference


1999-2015

1653
.

Product Version 15.1


All Rights Reserved.

Solution/Workaround
The parameter small should be a factor of large.

See Also

swap() on page 1069

ERR_TE_NOFUNC
Error Type
Semantic

Description
This error occurs when you use a function call inside a temporal repeat operator [].

Example
wait [foo()] * cycle;

Typical Error Message


Functions cannot be called from temporal repeat operator []

Solution/Workaround
Example 1
wait [foo()] * cycle; -- is not supported

Workaround:
Use a temporary variable as in
var t : int = foo();
wait [t] * cycle;

Example 2
In the case of an event or expect:

Specman e Language Reference


1999-2015

1654

Product Version 15.1


All Rights Reserved.

event m is { @a; [foo()] };

-- is not supported

Workaround:
Use a temporary field and assign it inside an exec:
!temp :int ;
event m is {@a exec { temp = foo()} ; [temp] }}

ERR_UNPACK_EMPTY_LIST
Error Type
Semantic

Description
This error occurs during an unpack operation.
The error message appears when the unpack process finished passing over the given list, but the
required struct was not fully passed over.

Typical Error Message


*** Error: Ran out of data while trying to unpack (use trace
packing for further details)

Solution/Workaround
Try to debug the problem using the trace packing.
Sometimes this problem occurs when a physical field of a list type is in the struct and the list size is
unbounded. In this case the list will exhaust all the items of the list-of-bit and the following fields will
not have a value. To overcome this problem, use the following size constraint:
<'
struct packet {
size: int;
%data[size]: list of int;
};
'>

Specman e Language Reference


1999-2015

1655
.

Product Version 15.1


All Rights Reserved.

See Also

trace on packing in the Specman Command Reference

show pack in the Specman Command Reference

show unpack in the Specman Command Reference

ERR_NAME_USED_TWICE_IN_SCOPE
Error Type
Semantic

Description
This error message occurs when a name was defined twice in one scope. The namespace is made up of a
variable and parameter, each with a unique name.

Example 1
var x : uint ;
var x : uint ;

Example 2
test (x: uint) is (var x : uint)

Typical Error Message:


*** Error: Name x already used in current scope

Solution/Workaround:
Example 1
var x : uint ;
{var x : uint; ...};

Example 2
test (x: uint) is { {var x : uint; ...} } ;

Specman e Language Reference


1999-2015

1656

Product Version 15.1


All Rights Reserved.

ERR_VOID_ERR
Error Type
Semantic

Description
Unlike C, a Specman action does not return a value; therefore, the return value of an action is void. This
error occurs when an action not returning a value is used as an expression.

Example
vpa-tool> print x.init();

Typical Error Message


*** Error: init() is void, while expecting some type

Solution/Workaround
Either:

If the called method should return a value, but the declaration is incorrect, correct the declaration.

If the action used is incorrect, use the correct action.

See Also

ERR_RETURN_VAL on page 1651

Specman e Language Reference


1999-2015

1657
.

Product Version 15.1


All Rights Reserved.

Specman e Language Reference


1999-2015

1658

Product Version 15.1


All Rights Reserved.

Você também pode gostar