Sie sind auf Seite 1von 454

e Language Reference Manual

Preliminary

Legal Notice
Copyright 1998-2002 Verisity Design, Inc. All rights reserved. The contents of this document constitute valuable proprietary and condential property of Verisity Design, Inc.

Trademarks
Verisity is a trademark of Verisity Ltd or its subsidiaries (Verisity), registered in the United States and other jurisdictions. The Verisity logo, eVC, Invisible Specman, Lintrpt, Pure IP, Specman, Specman Elite, Specview, SureCov, SureLint, SureSight, and Verication Advisor are trademarks of Verisity Design, Inc. All other trademarks are the exclusive property of their respective owners.

Confidentiality Notice
No part of this information product may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, optical, or otherwise without prior written permission from Verisity Design, Inc. Information in this product is subject to change without notice and does not represent a commitment on the part of Verisity. The information contained herein is the proprietary and condential information of Verisity or its licensors, and is supplied subject to, and may be used only by Verisitys customers in accordance with, a written agreement between Verisity and its customers. Except as may be explicitly set forth in such agreement, Verisity does not make, and expressly disclaims, any representations or warranties as to the completeness, accuracy, or usefulness of the information contained in this document. Verisity does not warrant that use of such information will not infringe any third party rights, nor does Verisity assume any liability for damages or costs of any kind that may result from use of such information.

Restricted Rights Legend


Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraphs (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at DFARS 252.227-7013.

Destination Control Statement


All technical data contained in this product is subject to the export control laws of the United States of America. Disclosure to nationals of other countries contrary to United States law is prohibited. It is the readers responsibility to determine the applicable regulations and to comply with them.

Table of Contents
1 About This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-1
1.1 1.2 Conventions in This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-2 Syntax Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-3

e Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-1
2.1 Lexical Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 2.1.1 File Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 2.1.2 Code Segments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 2.1.3 Comments and White Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3 2.1.4 Literals and Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4 2.1.4.1 Unsized Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4 2.1.4.2 Sized Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-5 2.1.4.3 Predefined Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-6 2.1.4.4 Literal String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-6 2.1.4.5 Literal Character . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-7 2.1.5 Names and Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-8 2.1.5.1 Legal e Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-8 2.1.5.2 e Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-8 2.2 Syntactic Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-10 2.2.1 Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-10 2.2.2 Struct Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-12 2.2.3 Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-13 2.2.3.1 Creating or Modifying Variables . . . . . . . . . . . . . . . . . . 2-14 2.2.3.2 Executing Actions Conditionally . . . . . . . . . . . . . . . . . . 2-15 2.2.3.3 Executing Actions Iteratively . . . . . . . . . . . . . . . . . . . . . 2-15 2.2.3.4 Controlling Program Flow . . . . . . . . . . . . . . . . . . . . . . . 2-16

e Language Reference Manual

Preliminary

Table of Contents

2.3

2.4 2.5

2.6

2.7

2.8

2.2.3.5 Invoking Methods and Routines . . . . . . . . . . . . . . . . . . . 2-16 2.2.3.6 Performing Time-Consuming Actions . . . . . . . . . . . . . . 2-17 2.2.3.7 Detecting and Handling Errors . . . . . . . . . . . . . . . . . . . . 2-18 2.2.4 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-18 Struct Hierarchy and Name Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . 2-19 2.3.1 Struct Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-19 2.3.2 Referencing e Entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-20 2.3.2.1 Structs and Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-20 2.3.2.2 Method and Routine Names . . . . . . . . . . . . . . . . . . . . . . 2-22 2.3.2.3 Enumerated Type Values . . . . . . . . . . . . . . . . . . . . . . . . 2-23 2.3.3 Implicit Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-24 2.3.3.1 it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-24 2.3.3.2 me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-25 2.3.3.3 result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-26 2.3.3.4 index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-26 2.3.4 Name Resolution Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-26 2.3.4.1 Names that Include a Path . . . . . . . . . . . . . . . . . . . . . . . . 2-27 2.3.4.2 Names that Do Not Include a Path . . . . . . . . . . . . . . . . . 2-28 Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-29 Bitwise Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-31 2.5.1 ~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-31 2.5.2 & | ^ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-33 2.5.3 >> << . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-34 Boolean Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-36 2.6.1 ! (not) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-36 2.6.2 && (and) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-37 2.6.3 || (or) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-38 2.6.4 => . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-39 2.6.5 now . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-40 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-42 2.7.1 Unary + - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-42 2.7.2 + - * / % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-43 Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-45 2.8.1 < <= > >= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-45 2.8.2 == != . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-46 2.8.3 === !== . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-48 2.8.4 ~ !~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-51

ii

Preliminary

e Language Reference Manual

Table of Contents

2.8.5 in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-52 2.9 String Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-54 2.10 Extraction and Concatenation Operators . . . . . . . . . . . . . . . . . . . . . . . . . 2-56 2.10.1 [ ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-56 2.10.2 [ : ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-58 2.10.3 [ .. ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-61 2.10.4 { ; } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-63 2.10.5 %{} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-64 2.11 Scalar Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-66 2.11.1 [ range,...] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-66 2.11.2 (bits | bytes : width-exp) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-67 2.12 Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-68 2.12.1 list.list-method() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-69 2.13 Special-Purpose Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-71 2.13.1 is [not] a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-71 2.13.2 new . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-73 2.13.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-75 2.13.4 ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-77 2.13.5 ? : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-78

Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-1


3.1 Overview of e Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-1 3.1.1 e Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2 3.1.1.1 Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2 3.1.1.2 Scalar Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3 3.1.1.3 Enumerated Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . 3-5 3.1.1.4 Struct Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-6 3.1.1.5 Struct Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-7 3.1.1.6 List Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-11 3.1.1.7 The String Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-13 3.1.2 Untyped Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-13 3.1.3 Assignment Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-16 3.1.3.1 What is an Assignment?. . . . . . . . . . . . . . . . . . . . . . . . . . 3-16 3.1.3.2 Assignment to Different but Compatible Types . . . . . . . 3-18 3.1.4 Precision Rules for Operations . . . . . . . . . . . . . . . . . . . . . . . . . . 3-21 3.1.4.1 Expected Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-21 3.1.4.2 Operand Type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-21

e Language Reference Manual

Preliminary

iii

Table of Contents

3.1.5 Automatic Type Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-22 3.2 Defining and Extending Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-24 3.2.1 type enumerated scalar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-24 3.2.2 type scalar subtype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-26 3.2.3 type sized scalar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-28 3.2.4 extend type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-30

Structs, Fields and Subtypes . . . . . . . . . . . . . . . . . . . . . 4-1


4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 Structs Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2 Defining Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3 4.2.1 struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3 Extending Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-7 4.3.1 extend type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-7 Extending Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-10 Defining Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-12 4.5.1 field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-12 Defining List Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-15 4.6.1 list of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-15 Creating Subtypes with When . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-17 4.7.1 when . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-17 Defining Methods in Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-20 Defining Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-21 4.9.1 attribute field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-22

Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1
5.1 Units Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1 5.1.1 HDL Paths and Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-3 5.1.2 Limitations on Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4 5.2 Defining Units and Fields of Type Unit . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4 5.2.1 unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-5 5.2.2 field: unit-type is instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-9 5.2.3 field: unit-type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-11 5.2.4 field: list of unit instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-13 5.2.5 field: list of unit-type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-15

iv

Preliminary

e Language Reference Manual

Table of Contents

Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
6.1 Defining and Extending Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2 6.1.1 method is [inline] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2 6.1.2 method @event is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-5 6.1.3 method [@event] is also | first | only | inline only . . . . . . . . . . . . 6-9 6.1.4 method [@event] is undefined | empty . . . . . . . . . . . . 6-15 6.2 Invoking Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-18 6.2.1 tcm() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-19 6.2.2 start tcm() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-21 6.2.3 method() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-23 6.2.4 compute method() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-25 6.2.5 return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-27 6.3 Parameter Passing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-30 6.3.1 Scalar Parameter Passing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-31 6.3.2 Compound Parameter Passing . . . . . . . . . . . . . . . . . . . 6-31 6.3.3 Notes on Passing by Reference . . . . . . . . . . . . . . . . . . . 6-32

Creating and Modifying e Variables . . . . . . . . . . . . . . . . 7-1


7.1 7.2 7.3 7.4 About e Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1 var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-2 = . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-4 op= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-6

Control Flow Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1


8.1 Conditional Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1 8.1.1 if then else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2 8.1.2 case labeled-case-item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-3 8.1.3 case bool-case-item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-5 8.2 Iterative Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-7 8.2.1 while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-8 8.2.2 repeat until . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-10 8.2.3 for each in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-11 8.2.4 for from to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-14 8.2.5 for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-15 8.3 File Iteration Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-17

e Language Reference Manual

Preliminary

Table of Contents

8.3.1 for each line in file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-17 8.3.2 for each file matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-18 8.4 Actions for Controlling the Program Flow . . . . . . . . . . . . . . . . . . . . . . . 8-20 8.4.1 break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-20 8.4.2 continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-21

Checks and Error Handling . . . . . . . . . . . . . . . . . . . . . . . 9-1


9.1 Handling DUT Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-1 9.1.1 check that . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-2 9.1.2 dut_error() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-3 9.1.3 dut_error_struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-4 9.1.4 set_check() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-8 9.2 Handling User Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-10 9.2.1 warning() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-10 9.2.2 error() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-11 9.2.3 fatal() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-13 9.2.4 try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-14 9.3 Handling Programming Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-16 9.3.1 assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-16

10

Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1
10.1 Basic Concepts of Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1 10.1.1 Order of Evaluation of Soft Constraints . . . . . . . . . . . . . . . . . . . 10-2 10.1.2 Constraining Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2 10.1.2.1 List Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-3 10.1.2.2 List Item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-3 10.1.2.3 Multiple List Items. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-3 10.1.2.4 List of Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-3 10.1.2.5 Multiple Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-3 10.1.3 Constraining Bit Slices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-4 10.1.3.1 Bit Slice Constraints and Signed Entities . . . . . . . . . . . . 10-5 10.1.3.2 Bit Slice Constraints and Soft Constraints. . . . . . . . . . . . 10-6 10.2 Defining Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-6 10.2.1 keep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-7 10.2.2 keep struct-list.is_all_iterations() . . . . . . . . . . . . . . . . . . . . . . . 10-9 10.2.3 keep for each . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-11

vi

Preliminary

e Language Reference Manual

Table of Contents

10.2.4 10.2.5 10.2.6 10.2.7 10.2.8

keep soft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-13 keep soft select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-15 keep item.reset_soft() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-18 constraint-bool-exp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-20 constraint-item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-23

11

Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1
11.1 Events Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1 11.1.1 Causes of Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-3 11.1.2 Scope of Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-3 11.2 Events and Expects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-4 11.2.1 event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-4 11.2.2 expect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-6 11.2.3 assume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-8 11.3 Sampling Events Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-9 11.4 Predefined Events Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-11 11.4.1 General Predefined Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-11

12

Temporal Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . 12-1


12.1 Temporal Expressions Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-1 12.1.1 Temporal Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-3 12.1.2 Success of a Temporal Expression . . . . . . . . . . . . . . . . . . . . . . . 12-3 12.1.2.1 Notation in Temporals Graphics for Success or Failure . 12-4 12.1.3 How Context Determines Evaluation Points . . . . . . . . . . . . . . . 12-5 12.1.4 Using Verilog Objects in Temporal Expressions . . . . . . . . . . . . 12-6 12.1.5 Selected Applications of Temporal Expressions . . . . . . . . . . . . 12-7 12.1.5.1 Handling Overlapping Transactions . . . . . . . . . . . . . . . . 12-7 12.1.5.2 Restricting TE Matches . . . . . . . . . . . . . . . . . . . . . . . . . . 12-7 12.1.6 Forms for Common Temporal Expressions . . . . . . . . . . . . . . . . 12-8 12.1.6.1 Examples of Sequence Expressions . . . . . . . . . . . . . . . . 12-8 12.1.6.2 Examples of Behavioral Rule Checks . . . . . . . . . . . . . . . 12-9 12.2 Temporal Operators and Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-11 12.2.1 Precedence of Temporal Operators . . . . . . . . . . . . . . . . . . . . . 12-11 12.2.2 fail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-12 12.2.3 and . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-14

e Language Reference Manual

Preliminary

vii

Table of Contents

12.2.4 or . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-15 12.2.5 { exp ; exp } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-17 12.2.6 eventually . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-19 12.2.7 [num] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-20 12.2.8 [ exp..exp ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-22 12.2.9 ~[ exp..exp ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-24 12.2.10 => . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-27 12.2.11 @unary event operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-28 12.2.12 @ binary sampling operator . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-29 12.2.13 cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-31 12.2.14 true(exp) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-32 12.2.15 change(exp), fall(exp), rise(exp) . . . . . . . . . . . . . . . . . . . . . . . 12-33 12.2.16 exec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-36 12.3 Special Support for Model Checking . . . . . . . . . . . . . . . . . . . . . . . . . . 12-37 12.3.1 Existential Path Quantifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-37 12.3.2 exists(+) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-37

13

Time-Consuming Actions . . . . . . . . . . . . . . . . . . . . . . . 13-1


13.1 Synchronization Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-1 13.1.1 sync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-2 13.1.2 wait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-4 13.2 Concurrency Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-6 13.2.1 all of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-7 13.2.2 first of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-8

14

Coverage Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1


14.1 Defining Coverage Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1 14.1.1 cover . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1 14.2 Defining Basic Coverage Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-7 14.2.1 item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-7 14.3 Defining Cross Coverage Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-18 14.3.1 cross . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-18 14.4 Defining Transition Coverage Items . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-23 14.4.1 transition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-23 14.5 Extending Coverage Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-26 14.5.1 cover is also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-26

viii

Preliminary

e Language Reference Manual

Table of Contents

15

Simulation-Related Constructs . . . . . . . . . . . . . . . . . . . 15-1


15.1 Verilog Statements or Unit Members . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-1 15.1.1 verilog code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-2 15.1.2 verilog function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-3 15.1.3 verilog import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-5 15.1.4 verilog task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-7 15.1.5 verilog time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-9 15.1.6 verilog variable reg | wire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-10 15.1.7 verilog variable memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-12 15.2 VHDL Statements and Unit Members . . . . . . . . . . . . . . . . . . . . . . . . . 15-13 15.2.1 vhdl code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-13 15.2.2 vhdl driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-15 15.2.3 vhdl function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-17 15.2.4 vhdl procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-20 15.2.5 vhdl time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-23 15.3 Simulation-Related Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-24 15.3.1 force . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-24 15.3.2 release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-26 15.4 Simulation-Related Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-27 15.4.1 'HDL-pathname' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-28

16

Packing and Unpacking

. . . . . . . . . . . . . . . . . . . . . . . 16-1

16.1 Basic Packing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-2 16.1.1 A Simple Example of Packing . . . . . . . . . . . . . . . . . . . . . . . . . . 16-3 16.1.2 A Simple Example of Unpacking . . . . . . . . . . . . . . . . . . . . . . . . 16-5 16.1.3 Packing and Unpacking Scalar Expressions . . . . . . . . . . . . . . . . 16-6 16.1.4 Packing and Unpacking Strings . . . . . . . . . . . . . . . . . . . . . . . . . 16-8 16.1.5 Packing and Unpacking Structs . . . . . . . . . . . . . . . . . . . . . . . . . 16-9 16.1.6 Packing and Unpacking Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 16-10 16.2 Advanced Packing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-12 16.2.1 Using the Predefined pack_options Instances . . . . . . . . . . . . . 16-13 16.2.1.1 packing.low . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-13 16.2.1.2 packing.low_big_endian . . . . . . . . . . . . . . . . . . . . . . . . 16-14 16.2.1.3 packing.high . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-15 16.2.1.4 packing.high_big_endian . . . . . . . . . . . . . . . . . . . . . . . 16-16

e Language Reference Manual

Preliminary

ix

Table of Contents

16.2.1.5 packing.network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-17 16.2.1.6 packing.global_default . . . . . . . . . . . . . . . . . . . . . . . . . 16-18 16.2.2 Customizing Pack Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-19 16.2.2.1 reverse_fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-19 16.2.2.2 reverse_list_items . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-20 16.2.2.3 scalar_reorder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-21 16.2.2.4 final_reorder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-22 16.2.3 Customizing Packing for a Particular Struct . . . . . . . . . . . . . . 16-23 16.2.4 Bit Slice Operator and Packing . . . . . . . . . . . . . . . . . . . . . . . . 16-23 16.2.5 Implicit Packing and Unpacking . . . . . . . . . . . . . . . . . . . . 16-24

17

Preprocessor Directives . . . . . . . . . . . . . . . . . . . . . . . . 17-1


17.1 define . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-2 17.2 #ifdef, #ifndef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-4

18

Importing e Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-1


18.1 import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-1

Index

Preliminary

e Language Reference Manual

About This Book

The e language is an object-oriented programming language. Although e can be used to create any general-purpose software program, it has been designed to facilitate the verication of electronic designs. The verication-specic constructs that distinguish e from other object-oriented languages such as C++ include:

Constructs to dene legal values for data items (constraints) Constructs to describe sequences over time (temporal constructs) Constructs to support concurrency (multi-threaded execution) Constructs to support connectivity (bit-level access)
The e language also is designed to reduce the effort required to write tests and to make the high-level intent of the test readily apparent. In contrast to other object-oriented programming languages, es unique extensibility lets you modify multiple data objects in a single, separate test le that is layered on top of the base verication environment. This extensibility feature allows you to address systemic, test-specic concerns that are not localized to a single data objects boundaries in a way that does not sacrice modularity or readability. The e Language Reference Manual provides detailed information on the e programming language. For information on es built-in (predened) methods and routines, refer to e Libraries.

e Language Reference Manual

Preliminary

1-1

About This Book

Conventions in This Book

1.1

Conventions in This Book

This manual uses visual cues to help you locate and interpret information easily. These cues are explained in Table 1-1. Table 1-1 Document Conventions Represents The Courier font indicates e or HDL code. For example, the following line indicates e code:
keep opcode in [ADD, ADDI];

Visual Cue
courier

bold

The bold font is used in descriptive text to indicate keywords. For example, the following sentence contains the keyword keep: Use the keep construct to dene legal values for data items. The bold font is used in syntax descriptions to indicate text that must be typed exactly as it appears. For example, in the following sentence the keywords keep and reset_soft, as well as the period and the parentheses must be typed as they appear: keep item.reset_soft()

italic

The italic font represents user-dened variables that you must provide. For example, the following line instructs you to type keep as it appears, and then specify a Boolean expression: keep constraint-bool-exp

[ ] square brackets

Square brackets indicate optional parameters. For example, in the following construct the keywords list of are optional: var name: [list of] type

[ ] bold brackets

Bold square brackets are required. For example, in the following construct you must type the bold square brackets as they appear: extend enum-type-name: [name,]

1-2

Preliminary

e Language Reference Manual

Syntax Notation

About This Book

Table 1-1

Document Conventions (continued) Represents An item, followed by a separator (usually a comma or a semicolon) and an ellipsis is an abbreviation for a list of elements of the specied type. For example, the following line means you can type a list of zero or more names separated by commas. extend enum-type-name: [name,]

Visual Cue construct,

The | character indicates alternative syntax or parameters. For example, the following line indicates that either the bits or bytes keyword should be used: type scalar-type (bits | bytes: num)

1.2

Syntax Notation

Each construct section starts with the syntax for the construct. The syntax shows the construct, any arguments it accepts with their types, and the constructs return type if it has one. When using the construct, terms in bold in the syntax are to be entered exactly as shown. Terms in italics are to be replaced by terms of your own. The argument types and the construct return type are for information only and are not entered. For example, the syntax notation for the predened pseudo-method named list.rst() on page 3-33 in e Libraries is list.rst(exp: bool): list-type This is what the notation means:

The bold .rst and the parentheses must be entered exactly. The parts in italics, list and exp, must be replaced by a list name and an expression. : bool indicates that the expression must be a Boolean expression. : list-type means that the pseudo-method returns an item of the list element type.
An example of a call to the list.rst() pseudo-method is shown below, where numbers is a list of integer items and my_number is an integer. The pseudo-method returns the rst integer in the list greater than 5:
my_number = numbers.first(it > 5)

e Language Reference Manual

Preliminary

1-3

About This Book

Syntax Notation

1-4

Preliminary

e Language Reference Manual

e Basics

This chapter describes the structure of an e program, starting with the organization of e code into one or more les 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 2-2 Syntactic Elements on page 2-10 Struct Hierarchy and Name Resolution on page 2-19 Operator Precedence on page 2-29 Bitwise Operators on page 2-31 Boolean Operators on page 2-36 Arithmetic Operators on page 2-42 Comparison Operators on page 2-45 Extraction and Concatenation Operators on page 2-56 Scalar Modiers on page 2-66 Parentheses on page 2-68 Special-Purpose Operators on page 2-71

e Language Reference Manual

Preliminary

2-1

e Basics

Lexical Conventions

See Also
Chapter 12, Temporal Expressions Chapter 3, Data Types Chapter 4, Predened Routines in e Libraries

2.1

Lexical Conventions

The following sections describe the lexical conventions of e:

File Structure on page 2-2 Code Segments on page 2-2 Comments and White Space on page 2-3 Literals and Constants on page 2-4 Names and Keywords on page 2-8

2.1.1

File Structure

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

See Also
Names and Keywords on page 2-8 Code Segments on page 2-2 Comments and White Space on page 2-3

2.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; 2-2 Preliminary

e Language Reference Manual

Comments and White Space


'>

e Basics

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

See Also
Comments and White Space on page 2-3 Statements on page 2-10

2.1.3

Comments and White Space

e les begin as a comment which ends when the rst 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 2-2

e Language Reference Manual

Preliminary

2-3

e Basics

Literals and Constants

2.1.4

Literals and Constants

Literals are numeric, character and string values specied 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 2-4 Sized Numbers on page 2-5 Predened Constants on page 2-6 Literal String on page 2-6 Literal Character on page 2-7

2.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 Unbounded Integers on page 3-4 for more information. The notations shown in Table 2-1 can be used to represent unsized numbers. Table 2-1 Notation Decimal integer Representing Unsized Numbers in Expressions Legal Characters Any combination of 0-9 possibly preceded by a hyphen - for negative numbers. An underscore (_) can be added anywhere in the number for readability. Any combination of 0-1 preceded by 0b. An underscore (_) can be added anywhere in the number for readability. Any combination of 0-9 and a-f preceded by 0x. An underscore (_) can be added anywhere in the number for readability. Examples 12, 55_32, -764

Binary integer

0b100111, 0b1100_0101 0xff, 0x99_aa_bb_cc

Hexadecimal integer

2-4

Preliminary

e Language Reference Manual

Literals and Constants

e Basics

Table 2-1 Notation

Representing Unsized Numbers in Expressions (continued) Legal Characters Any combination of 0-7 preceded by 0o. An underscore (_) can be added anywhere in the number for readability. A decimal integer followed by a K or k. For example, 32K = 32768. A decimal integer followed by an M or m. For example, 2m = 2097152. Examples 0o66_123

Octal integer

K (kilo: multiply by 1024) M (mega: multiply by 1024*1024)

32K, 32k, 128k 1m, 4m, 4M

See Also
Literals and Constants on page 2-4

2.1.4.2

Sized Numbers

A sized number is a notation that denes a literal with a specic 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 specied in one of four radixes, as shown in Table 2-2. Note If the value number is more than the specied size in bits, its most signicant bits are ignored. If the value number is less that the specied size, it is padded by zeros.

Table 2-2 Radix Binary Octal Decimal

Radix Specication Characters Represented By A leading 'b or 'B A leading 'o or 'O A leading 'd or 'D A leading 'h or 'H or 'x or 'X
Preliminary

Example 8'b11001010 6'o45 16'd63453 32'h12ffab04


2-5

Hexadecimal

e Language Reference Manual

e Basics

Literals and Constants

See Also
Literals and Constants on page 2-4

2.1.4.3

Predefined Constants

A set of constants is predened in e, as shown in Table 2-3. Table 2-3 Constant TRUE FALSE NULL UNDEF MAX_INT MIN_INT MAX_UINT Predened Constants Description For Boolean variables and expressions. For Boolean variables and expressions. For structs, species a NULL pointer. For character strings, species an empty string. UNDEF indicates NONE where an index is expected. Represents the largest 32-bit int (231 -1) Represents the smallest 32-bit int (-231). Represents the largest 32-bit uint (232-1).

See Also
Literals and Constants on page 2-4

2.1.4.4

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 2-4 are allowed. Table 2-4 Escape Sequences in Strings Meaning New-line

Escape Sequence \n

2-6

Preliminary

e Language Reference Manual

Literals and Constants

e Basics

Table 2-4

Escape Sequences in Strings (continued) Meaning Tab Form-feed Quote Backslash Carriage-return

Escape Sequence \t \f \" \\ \r

Example
This example shows escape sequences used in strings.
extend sys { m() is { var header: string = "Name\tSize in Bytes\n----\t-------------\n"; var p: packet = new; var pn: string = p.type().name; var ps: uint = p.type().size_in_bytes; outf("%s%s\t%d", header, pn, ps); }; };

See Also
Literals and Constants on page 2-4

2.1.4.5

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.

e Language Reference Manual

Preliminary

2-7

e Basics

Names and Keywords

See Also
Literals and Constants on page 2-4

2.1.5

Names and Keywords

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

Legal e Names on page 2-8 e Keywords on page 2-8

2.1.5.1

Legal e Names

User-dened 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 are not recommended for general use. Names beginning with a number are not allowed. The syntax of an e module name (a le name) is the same as the syntax of UNIX le names, with the following exceptions:

@ and ~ are not allowed as the rst character of a le name. [, ], {, } are not allowed in le names. Only one . is allowed in a le name.
Note Many ASCII characters are not handled correctly by some UNIX commands when used in le names. These characters include control characters, spaces, and characters reserved for command line parsing, such as -, |, and <.

2.1.5.2

e Keywords

The keywords listed below are the components of the e language. Some of the terms are keywords only when used together with other terms, such as key in list(key:key). all of assert bit bytes compute all_values assume bits c export computed and async bool case consume as a attribute break change continue as_a before byte check that cover

2-8

Preliminary

e Language Reference Manual

Names and Keywords

e Basics

cross default down to emit fail force if int is rst is only key me not in or range reverse soft string time type var verilog task vhdl code vhdl simulator within

cvl call dene dut_error event fall from #ifdef is a is inline is undened like nand now others ranges rise start sync to uint verilog code verilog time vhdl driver vhdl time

cvl callback delay each exec le gen #ifndef is also is instance item line new nxor pass release routine state machine sys transition unit

cvl method detach edges expect rst of global in is c routine is not a keep list of nor on prev repeat select step that true until

cycle do else extend for hdl pathname index is empty is not empty keeping matching not only print return session struct then try using verilog simulator verilog variable vhdl driver with

verilog function verilog import verilog timescale verilog trace vhdl function when vhdl procedure while

e Language Reference Manual

Preliminary

2-9

e Basics

Syntactic Elements

2.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: Statements Statements are top-level constructs and are valid within the begin-code <' and end-code '> markers. See Statements on page 2-10 for a list and brief description of e statements. Struct members are second-level constructs and are valid only within a struct denition. See Struct Members on page 2-12 for a list and brief description of e struct members. 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 2-13 for a list and brief description of e actions. Expressions are lower-level constructs that can be used only within another e construct. See Expressions on page 2-18 for a list and brief description of e expressions.

Struct members

Actions

Expressions

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

See Also
Statements on page 2-10 Struct Members on page 2-12 Actions on page 2-13 Expressions on page 2-18

2.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.

2-10

Preliminary

e Language Reference Manual

Statements

e Basics

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; '>

In general, statements can appear in any order. However, within a given e module, import statements must appear before any other statements. No statements other than preprocessor directives or denes (#ifdef, #ifndef, dene, dene as, dene as computed) can precede import statements. Here is the complete list of e statements: struct on page 4-3 type Denes a new data structure. Denes an enumerated data type or scalar subtype. See type enumerated scalar on page 3-24, type scalar subtype on page 3-26, or type sized scalar on page 3-28 Modies a previously dened struct or type. See extend type on page 4-7 or extend type on page 3-30 Denes a data structure associated with an HDL component or block. Used together with dene statements to place conditions on the e parser. Reads in an e le. Reads in Verilog macro denitions from a le. Writes Verilog code to the stubs le, which is used to interface e programs with a Verilog simulator. Species Verilog simulator time resolution.

extend unit on page 5-5 #ifdef, #ifndef on page 17-4 import on page 18-1 verilog import on page 15-5 verilog code on page 15-2 verilog time on page 15-9

verilog variable reg | wire on Species a Verilog register or wire that you want to page 15-10 drive from e. verilog variable memory on Species a Verilog memory that you want to access page 15-12 from e. verilog function on page 15-3 Species a Verilog function that you want to call from e. verilog task on page 15-7 Species a Verilog task that you want to call from e.

e Language Reference Manual

Preliminary

2-11

e Basics

Struct Members

vhdl code on page 15-13 vhdl driver on page 15-15

Writes VHDL code to the stubs le, which is used to interface e programs with a VHDL simulator. Used to drive a VHDL signal continuously via the resolution function.

vhdl function on page 15-17 Declares a VHDL function dened in a VHDL package. vhdl procedure on page 15-20 Declares a VHDL procedure dened in a VHDL package. vhdl time on page 15-23 Species VHDL simulator time resolution.

See Also
Struct Members on page 2-12 Actions on page 2-13 Expressions on page 2-18

2.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 denition statement (see struct on page 4-3). 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; }; '>

2-12

Preliminary

e Language Reference Manual

Actions

e Basics

A struct can contain multiple struct members of any type in any order. Here is a brief description of e struct members: eld declaration method declaration Denes a data entity that is a member of the enclosing struct and has an explicit data type. Denes an operational procedure that can manipulate the elds of the enclosing struct and access run-time values in the DUT. Denes an instance of the parent struct in which specic struct members have particular values or behavior. Inuences the range of legal values for data entities. Denes functional test goals and collects data on how well the testing is meeting those goals. Denes e events and their associated actions.

subtype declaration constraint declaration coverage declaration temporal declaration

See Also
Dening Fields on page 4-12 Dening and Extending Methods on page 6-2 Creating Subtypes with When on page 4-17 Dening Constraints on page 10-6 Dening Coverage Groups on page 14-1

2.2.3

Actions

e actions are lower-level procedural constructs that can be used in combination to manipulate the elds 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, specically 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');

e Language Reference Manual

Preliminary

2-13

e Basics
on xmit_ready {transmit();}; transmit() is { out("transmitting packet..."); }; }; '>

Actions

The following sections describe the e actions:

Creating or Modifying Variables on page 2-14 Executing Actions Conditionally on page 2-15 Executing Actions Iteratively on page 2-15 Controlling Program Flow on page 2-16 Invoking Methods and Routines on page 2-16 Performing Time-Consuming Actions on page 2-17 Detecting and Handling Errors on page 2-18

2.2.3.1

Creating or Modifying Variables


Denes a local variable. Assigns or samples values of elds, local variables, or HDL objects. Performs a complex assignment (such as add and assign, or shift and assign) of a eld, local variable, or HDL object. Forces a Verilog net or wire to a specied value, over-riding the value from driven from the DUT. Releases the Verilog net or wire that was previously forced.

var on page 7-2 = on page 7-4 op= on page 7-6 force on page 15-24 release on page 15-26

See Also
Executing Actions Conditionally on page 2-15 Executing Actions Iteratively on page 2-15 Controlling Program Flow on page 2-16 Invoking Methods and Routines on page 2-16 Performing Time-Consuming Actions on page 2-17
2-14 Preliminary

e Language Reference Manual

Actions

e Basics

Detecting and Handling Errors on page 2-18

2.2.3.2

Executing Actions Conditionally

if then else on page 8-2 Executes an action block if a condition is met and a different action block if it is not. case labeled-case-item Executes one action block out of multiple action blocks on page 8-3 depending on the value of a single expression. case bool-case-item on Evaluates a list of Boolean expressions and executes the page 8-5 action block associated with the rst expression that is true.

See Also
Creating or Modifying Variables on page 2-14 Executing Actions Iteratively on page 2-15 Controlling Program Flow on page 2-16 Invoking Methods and Routines on page 2-16 Performing Time-Consuming Actions on page 2-17 Detecting and Handling Errors on page 2-18

2.2.3.3

Executing Actions Iteratively


Executes an action block repeatedly until a Boolean expression becomes FALSE. Executes an action block repeatedly until a Boolean expression becomes TRUE. For each item in a list that is a specied type, executes an action block. Executes an action block for a specied number of times. Executes an action block for a specied number of times.

while on page 8-8 repeat until on page 8-10 for each in on page 8-11 for from to on page 8-14 for on page 8-15

for each line in le on Executes an action block for each line in a le. page 8-17 for each le matching Executes an action block for each le in the search path. on page 8-18
e Language Reference Manual
Preliminary 2-15

e Basics

Actions

See Also
Creating or Modifying Variables on page 2-14 Executing Actions Conditionally on page 2-15 Controlling Program Flow on page 2-16 Invoking Methods and Routines on page 2-16 Performing Time-Consuming Actions on page 2-17 Detecting and Handling Errors on page 2-18

2.2.3.4

Controlling Program Flow


Breaks the execution of the enclosing loop.

break on page 8-20

continue on page 8-21 Stops execution of the enclosing loop and continues with the next iteration of the same loop.

See Also
Creating or Modifying Variables on page 2-14 Executing Actions Conditionally on page 2-15 Executing Actions Iteratively on page 2-15 Invoking Methods and Routines on page 2-16 Performing Time-Consuming Actions on page 2-17 Detecting and Handling Errors on page 2-18

2.2.3.5

Invoking Methods and Routines

method() on page 6-23 Calls a regular method. tcm() on page 6-19 start tcm() on page 6-21 Calls a TCM. Launches a TCM as a new thread (a parallel process).

2-16

Preliminary

e Language Reference Manual

Actions

e Basics

routine() on page 4-142 Calls an e predened routine. in e Libraries compute method() on Calls a value-returning method without using the value page 6-25 returned. return on page 6-27 Returns immediately from the current method to the method that called it.

See Also
Creating or Modifying Variables on page 2-14 Executing Actions Conditionally on page 2-15 Executing Actions Iteratively on page 2-15 Controlling Program Flow on page 2-16 Performing Time-Consuming Actions on page 2-17 Detecting and Handling Errors on page 2-18

2.2.3.6

Performing Time-Consuming Actions


Suspends execution of the current TCM until the temporal expression succeeds. Suspends execution of the current time-consuming method until a given temporal expression succeeds. 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. Executes multiple action blocks concurrently, as separate branches of a fork. The action following the rst of action is reached when any of the branches in the rst of has been fully executed.

sync on page 13-2 wait on page 13-4 all of on page 13-7

rst of on page 13-8

state machine on Denes a state machine. page 5-2 in e Libraries

See Also
Creating or Modifying Variables on page 2-14
e Language Reference Manual
Preliminary 2-17

e Basics

Expressions

Executing Actions Conditionally on page 2-15 Executing Actions Iteratively on page 2-15 Controlling Program Flow on page 2-16 Invoking Methods and Routines on page 2-16 Detecting and Handling Errors on page 2-18

2.2.3.7

Detecting and Handling Errors

check that on page 9-2 Checks the DUT for correct data values. dut_error() on page 9-3 assert on page 9-16 Denes a DUT error message string. Issues an error message if a specied Boolean expression is not true. Issues an error message when a user error is detected. Issues an error message, halts all activities, and exits immediately. Catches errors and exceptions.

warning() on page 9-10 Issues a warning message. error() on page 9-11 fatal() on page 9-13 try on page 9-14

See Also
Creating or Modifying Variables on page 2-14 Executing Actions Conditionally on page 2-15 Executing Actions Iteratively on page 2-15 Controlling Program Flow on page 2-16 Invoking Methods and Routines on page 2-16 Performing Time-Consuming Actions on page 2-17

2.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.
2-18 Preliminary

e Language Reference Manual

Struct Hierarchy and Name Resolution

e Basics

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 eld 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 An e entity, such as a method, eld, list, or struct An HDL entity, such as a signal
A compound expression applies one or more operators to one or more operands.

See Also
Chapter 3, Data Types

2.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 2-19 Referencing e Entities on page 2-20 Implicit Variables on page 2-24 Name Resolution Rules on page 2-26

2.3.1

Struct Hierarchy

Because structs can be instantiated as the elds of other structs, a typical e program has many levels of hierarchy. Every e program contains several predened structs as well as user-dened structs. The predened struct global is the root of all e structs. global contains predefined structs that act as libraries of predefined functionality and are directly accessible from any location in an e program. It is highly recommended that you do not extend the global struct. Instead, you should extend the sys struct to add user-dened structs or units.
e Language Reference Manual
Preliminary 2-19

e Basics

Referencing e Entities

Figure 2-1 shows the partial hierarchy of a typical e program. The predened structs are shown in bold. Figure 2-1 Diagram of Struct Hierarchy

global sys switch ctrl_stub port_stub1 sender port_stub2 port_stub3 port_stub4

listener

2.3.2

Referencing e Entities

The following sections describe how to reference e entities:

Structs and Fields on page 2-20 Method and Routine Names on page 2-22 Enumerated Type Values on page 2-23

2.3.2.1

Structs and Fields

Any user-dened struct can be instantiated as a eld of the sys struct or of another struct. Thus every instantiated struct and its elds have a place in the struct hierarchy and their names include a path reecting that place. The keep constraints in the following example show the use of paths to identify the elds u and kind:
<' struct switch { ctrl: ctrl_stub; port: port_stub; keep soft port.sender.cell.u == 0xff; 2-20 Preliminary

e Language Reference Manual

Referencing e Entities
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; }; '>

e Basics

Notes
The name of the global struct can be omitted from the path to a eld 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, prexing the name port.sender.cell.u in the example above with the name of the enclosing struct, switch, is not legal.

In certain contexts, you can use the implicit variables me or it in the path to refer to the
enclosing struct. For example, prexing the name port.sender.cell.u in the example above with me is legal. See Implicit Variables on page 2-24 for more information.

A special syntax is required to reference struct subtypes and elds under struct subtypes.
This syntax is described in Struct Subtypes on page 3-7.

See Also
Struct Subtypes on page 3-7 Implicit Variables on page 2-24

e Language Reference Manual

Preliminary

2-21

e Basics

Referencing e Entities

. on page 2-75

2.3.2.2

Method and Routine Names

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

Some predened 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; }; '>

2-22

Preliminary

e Language Reference Manual

Referencing e Entities

e Basics

User-dened routines, like predened routines, are associated with the global struct. You can omit global from the path when the context is unambiguous. See Name Resolution Rules on page 2-26 for more information.

See Also
Invoking Methods and Routines on page 2-16

2.3.2.3

Enumerated Type Values

Names for enumerated type values must be unique within each type. For example, dening a type as my_type: [a, a, b] is not legal 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 dene 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 eld 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:
value'field_name

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;

However, because the type of the variable tmp below is not specied, 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 3-5

e Language Reference Manual

Preliminary

2-23

e Basics

Implicit Variables

2.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 2-24 me on page 2-25 result on page 2-26 index on page 2-26
Note With the exception of result, it is illegal to assign values to implicit variables.

2.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
The implicit variable it always refers to the current item. Wherever it.eld can be used, the shorthand notation .eld 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; }; 2-24 Preliminary

e Language Reference Manual

Implicit Variables

e Basics

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 2-24

2.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 struct, sys.
extend sys { my_list: list of int; run() is also { print me.my_list.is_empty(); check that (me.my_list.size() > 5) }; };

When referring to a eld 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; keep header.dest == 0x55; }; struct header { %dest : int (bits : 8); };

See Also
Implicit Variables on page 2-24
e Language Reference Manual
Preliminary 2-25

e Basics

Name Resolution Rules

2.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 following method returns the sum of a and b:
sum(a: int, b: int): int is { result = a + b; };

See Also
Implicit Variables on page 2-24

2.3.3.4

index

The constructs that create the implicit variable index are:

list pseudo-methods for each keep for each


The index variable holds the current index of the item referred to by it. The scope of the index variable is limited to the action block. The following loop assigns 5 to the len eld of every item in the packets list and also assigns the index value of each item to its id eld.
for each in packets do { packets[index].len = 5; .id = index; };

See Also
Implicit Variables on page 2-24

2.3.4

Name Resolution Rules

The following sections describe how e names are resolved, depending on whether the names include a path or not.

Names that Include a Path on page 2-27


2-26 Preliminary

e Language Reference Manual

Name Resolution Rules

e Basics

Names that Do Not Include a Path on page 2-28

2.3.4.1

Names that Include a Path

If a name includes a path, an entity of that name must exist at the specied scope. In the following example, the names sys.b.u or .u in the keep constraints cannot be resolved. All other names can be resolved.
<' struct b { u:uint; m() is { print u; }; }; struct c { u:uint; keep u > sys.bi.u; keep me.u > 5; -- keep u < sys.b.u; -- keep .u < sys.bi.u; m() is { print u; }; }; extend sys { bi: b; ci: c; run() is also { sys.bi.m(); ci.m(); }; }; '>

// sys does not have a field b // no such variable it

Note If the path begins with a period (.), the path is assumed to begin with the implicit variable it.

See Also
Names that Do Not Include a Path on page 2-28
e Language Reference Manual
Preliminary 2-27

e Basics

Name Resolution Rules

2.3.4.2

Names that Do Not Include a Path

If a name does not include a path, the following checks are performed, in order. If a check identies the named object, the subsequent checks are not performed. 1. Check whether the name is a macro. If there are two macro denitions, choose the most recent one. 2. Check whether the name is one of the predened constants. There cannot be two identical predened constants. 3. Check whether the name is an enumerated type. There cannot be two identical enumerated types. 4. Check whether the name identies a variable used in the current action block. If not, and if the action is nested, check whether the name identies 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 identies a member of the current struct:

If the expression is inside a struct denition, the current struct is the enclosing struct. If the expression is inside a method, the current struct is the struct to which the
method belongs. 6. Check whether the name identies a member of the global struct. 7. If the name is still unresolved, issue an error message. Note Macros, predened 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 user-dened constant can have the same name as a predened e constant


(Predened Constants on page 2-6).

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

See Also
Names that Include a Path on page 2-27

2-28

Preliminary

e Language Reference Manual

Operator Precedence

e Basics

2.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 rst. Table 2-5 Operator [ ] on page 2-56 [ .. ] on page 2-61 [ : ] on page 2-58 f() . on page 2-75 ~ on page 2-31, ! (not) on page 2-36 { ; } on page 2-63 %{} on page 2-64 Unary + - on page 2-42 *, /, % +, >> << on page 2-34 < <= > >= on page 2-45 is [not] a on page 2-71 Operators in Order of Precedence Operation Type List indexing (subscripting) List slicing Bit slicing (selection) Method and routine calls (see Invoking Methods and Routines on page 2-16) Field selection Bitwise not, Boolean not

List concatenation Bit concatenation Unary plus, minus Binary multiply, divide, modulus (see + - * / % on page 2-43) Binary add and subtract (see + - * / % on page 2-43) Shift right, shift left Comparison Subtype identication

e Language Reference Manual

Preliminary

2-29

e Basics

Operator Precedence

Table 2-5 Operator == != on page 2-46

Operators in Order of Precedence (continued) Operation Type Equality, inequality Verilog four-state comparison String matching Range list operator Bitwise and (see & | ^ on page 2-33) Bitwise or (see & | ^ on page 2-33) Bitwise xor (see & | ^ on page 2-33) Boolean and Boolean or Boolean implication Conditional operator (a ? b : c means if a then b else c)

=== !== on page 2-48 ~ !~ on page 2-51 in on page 2-52 & | ^ && (and) on page 2-37 || (or) on page 2-38 => on page 2-39 ? : on page 2-78

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 3, Data Types for information on the precision of operations and assignment
rules

2-30

Preliminary

e Language Reference Manual

Bitwise Operators

e Basics

2.5

Bitwise Operators
The bitwise unary negation operator changes each 0 bit to 1 and each 1 bit to 0 in a single expression. 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. The shift-right and shift-left operators shift the bits in an expression to the left or right a specied number of bits.

The following sections describe the e bitwise operators: ~ on page 2-31 & | ^ on page 2-33

>> << on page 2-34

See Also
bitwise_op() on page 4-23 in e Libraries

2.5.1
Purpose

Unary bitwise negation

Category
Expression

Syntax
~exp Syntax example:
print ~x using hex;

Parameter
exp A numeric expression or an HDL pathname.

e Language Reference Manual

Preliminary

2-31

e Basics

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.
m() is { var x : int = 0xff; print ~x using hex; };

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

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

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2 Untyped Expressions on page 3-13

2-32

Preliminary

e Language Reference Manual

&|^

e Basics

2.5.2
Purpose

&|^

Binary bitwise operations

Category
Expression

Syntax
exp1 operator exp2 Syntax example:
print (x & y);

Parameters
exp1, exp2 & | ^ A numeric expression or an HDL pathname. Performs an AND operation. Performs an OR operation. Performs an XOR operation. operator is one of the following:

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

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

Example 2
m() is {

e Language Reference Manual

Preliminary

2-33

e Basics
var x: uint = 0xff03; 'top.a' = 0x70f6; print (x | 'top.a'); };

>> <<

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

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.5.3
Purpose

>> <<

Shift bits left or right

Category
Expression

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

2-34

Preliminary

e Language Reference Manual

>> <<

e Basics

Parameters
exp1 << >> exp2 A numeric expression or an HDL pathname. Performs a shift-left operation. Performs a shift-right operation. A numeric expression. operator is one of the following:

Description
Shifts each bit of the rst expression to the right or to the left the number of bits specied by the second expression. In a shift-right operation, the shifted bits on the right are lost, while on the left they are lled with 1, if the rst 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 lled with 0. If the bit size of the second expression is greater than 32 bits, it is rst truncated to 32 bits, and then the shift is performed. Truncation removes the most signicant bits.

Note
The result of a shift by more than 32 bits is undened.

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

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

e Language Reference Manual

Preliminary

2-35

e Basics

Boolean Operators

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.6

Boolean Operators
Returns TRUE when an expression evaluates to FALSE, and vice versa. Returns TRUE if two expressions are both TRUE. Returns TRUE if one of two expressions is TRUE. Returns TRUE when the rst expression of two expressions is FALSE, or when both expressions are TRUE. Returns TRUE if an event has occurred in the current cycle.

The following sections describe the e Boolean operators: ! (not) on page 2-36 && (and) on page 2-37 || (or) on page 2-38 => on page 2-39

now on page 2-40

2.6.1
Purpose

! (not)

Boolean not operation

Category
Expression

Syntax
!exp not exp Syntax example:
out(!(3 > 2));

2-36

Preliminary

e Language Reference Manual

&& (and)

e Basics

Parameters
exp A Boolean expression or an HDL pathname.

Description
Returns FALSE when the expression evaluates to TRUE (not equal to 0) and returns TRUE when the expression evaluates to FALSE (0).

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

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.6.2
Purpose

&& (and)

Boolean and

Category
Expression

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

e Language Reference Manual

Preliminary

2-37

e Basics
};

|| (or)

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' > 2) then { out("'top.a' > 'top.b' > 1"); }; };

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.6.3
Purpose

|| (or)

Boolean or

Category
Expression

Syntax
exp1 || exp2 exp1 or exp2 Syntax example:
2-38 Preliminary

e Language Reference Manual

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

e Basics

Parameters
exp1, exp2 A Boolean expression or an HDL pathname.

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

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

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.6.4
Purpose

=>

Boolean implication

Category
Expression

Syntax
exp1 => exp2

e Language Reference Manual

Preliminary

2-39

e Basics

now

Syntax example:
out((2 > 1) => (3 > 2));

Parameters
exp1, exp2 A Boolean expression.

Description
The expression returns TRUE when the rst 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)); };

See Also
constraint-bool-exp on page 10-20 Scalar Types on page 3-2

2.6.5
Purpose

now

Boolean event check

Category
Boolean expression

Syntax
now @event-name
2-40 Preliminary

e Language Reference Manual

now

e Basics

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

Parameter
event 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(); }; };

See Also
Chapter 11, Events Scalar Types on page 3-2

e Language Reference Manual

Preliminary

2-41

e Basics

Arithmetic Operators

2.7

Arithmetic Operators
Perform arithmetic operations on a single operand. Perform arithmetic operations on two operands.

The following sections describe the e arithmetic operators: Unary + - on page 2-42 + - * / % on page 2-43

2.7.1
Purpose

Unary + -

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); }; 2-42 Preliminary

e Language Reference Manual

+-*/%

e Basics

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

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.7.2
Purpose

+-*/%

Binary arithmetic

Category
Expression

Syntax
exp1 operator exp2 Syntax example:
out(10 + 5);

Parameters
exp1, exp2 + A numeric expression or an HDL pathname. Performs addition. Performs subtraction. operator is one of the following:

e Language Reference Manual

Preliminary

2-43

e Basics

+-*/%

* / %

Performs multiplication. Performs division and returns the quotient, rounded down. Performs division and returns the remainder.

Description
Performs binary arithmetic operations.

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

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

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

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2 Arithmetic Routines on page 4-12 in e Libraries

2-44

Preliminary

e Language Reference Manual

Comparison Operators

e Basics

2.8

Comparison Operators

The following sections describe the e comparison operators: < <= > >= on page 2-45 Compares two numeric expressions or HDL pathnames. == != on page 2-46 Determines whether two expressions are equal or not. === !== on page 2-48 Performs a 4-state, Verilog-style comparison of HDL objects. ~ !~ on page 2-51 in on page 2-52 Determines whether two string expressions are equal or not. Determines whether an expression is in a list or a range.

2.8.1
Purpose

< <= > >=

Comparison of values

Category
Expression

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

Parameters
exp1, exp2 < A numeric expression, or an HDL pathname. Returns TRUE if the rst expression is smaller than the second expression. operator is one of the following:

e Language Reference Manual

Preliminary

2-45

e Basics

== !=

<= > >=

Returns TRUE if the rst expression is not larger than the second expression. Returns TRUE if the rst expression is larger than the second expression. Returns TRUE if the rst expression is not smaller than the second expression.

Description
Compares two expressions.

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

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.8.2
Purpose

== !=

Equality of values

Category
Expression

Syntax
exp1 operator exp2 Syntax example:
print lob1 == lob2; print p1 != p2; 2-46 Preliminary

e Language Reference Manual

== !=

e Basics

Parameters
exp1, exp2 == != A numeric, Boolean, string, list, or struct expression. Returns TRUE if the rst expression evaluates to the same value as the second expression. Returns TRUE if the rst expression does not evaluate to the same value as the second expression. operator is one of the following

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 2-6. Table 2-6 Type integers, unsigned integers, Booleans, HDL pathnames strings lists structs Equality Comparisons for Various Data Types Comparison Method Values are compared. The strings are compared character by character. The lists are compared item by item. The structs addresses are compared

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 2-48 for a description of using this operator with HDL pathnames.

Example
extend sys { p1: packet; p2: packet; m() is {

e Language Reference Manual

Preliminary

2-47

e Basics
var var var var

=== !==
s: string = "/rtests/tmp"; b: bool = TRUE; lob1: list of byte = {0xaa; 0xbb; 0xcc; 0xdd}; lob2: list of byte = lob1; s == "/rtests/tmp"; b != FALSE; lob1 == lob2; p1 != p2;

print print print print }; };

See Also
=== !== on page 2-48 ~ !~ on page 2-51 'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.8.3
Purpose

=== !==

Verilog-style four-state comparison operators

Category
Expression

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

2-48

Preliminary

e Language Reference Manual

=== !==

e Basics

Parameters
HDL-pathname The full path name of an HDL object, optionally including expressions and composite data. See 'HDL-pathname' on page 15-28 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. Either a literal with four-state values, a numeric expression, or another HDL pathname.

===

!== == != exp

Description
Compares four-state values (0, 1, x and z) with the identity and nonidentity operators (Verilog style operators). Alternatively, you can use the regular equal and non-equal operators. (A description of the regular identity and nonidentity operators is included in Parameters on page 2-49, for clarity.) There are three ways to use the identity (===) and nonidentity (!==) 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).
e Language Reference Manual
Preliminary 2-49

e Basics

=== !==

Example 1
In e 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' 'TOP.write_en' 'TOP.write_en' 'TOP.write_en' }; 2-50 === === === === 1'b0: 1'b1: 1'bx: 1'bz: {out("write_en {out("write_en {out("write_en {out("write_en is is is is 0");}; 1");}; x");}; z");};

Preliminary

e Language Reference Manual

~ !~

e Basics

See Also
'HDL-pathname' on page 15-28 Scalar Types on page 3-2

2.8.4
Purpose

~ !~

String matching

Category
Expression

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

Parameters
string ~ !~ pattern-string A legal e string. Returns TRUE if the pattern string can be matched to the whole string. Returns TRUE if the pattern string cannot be matched to the whole string. An AWK-style regular expression. See String Matching on page 2-54 for more information. operator is one of the following:

Description
Matches a string against an AWK-style regular expression.

e Language Reference Manual

Preliminary

2-51

e Basics

in

After a match using either of the two styles, a local pseudo-variable $0 holds the whole matched string, and the pseudo-variables $1, $2,$27 hold the sub strings matched. The pseudo-variables are set only by the ~ operator and are local to the function that does the string match. If the ~ operator produces fewer than 28 substrings, then the unneeded variables are left empty.

Example 1
m() is { var s: string = "BlueBird"; print s ~ "/^Bl.*d$/"; print s ~ "/^bl.*d$/"; };

Example 2
m() is { var s: string = "BlueBird"; print s !~ "/^Bl.*d$/"; };

See Also
The String Type on page 3-13

2.8.5
Purpose

in

Check for value in a range

Category
Expression

Syntax
exp1 in exp2 Syntax example:
check that x in {1;2;3;4;5}; 2-52 Preliminary

e Language Reference Manual

in

e Basics

Parameters
exp1 When the second expression is a range list then the type of the rst expression has to be of a type comparable to the type of the range list. When the second expression is a list then the type of the first expression can be one of the following:

A type that is comparable to the element type of the second expression. A list of type that is comparable to the element type of the second
expression. exp2 Either a list or a range list. A range list is a list of constants or expressions that evaluate to constants. Expressions that use variables or struct elds cannot appear in range lists.

Description
Evaluates TRUE if the rst expression is included or contained in the second expression.

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

Example 2
When two lists are compared and the rst 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 rst check makes sure that y contains 0 to 2 instances of the numbers 0, 1, 2, and 3. The second check fails.
e Language Reference Manual
Preliminary 2-53

e Basics
<' extend sys { y: list of uint (bits: 2); keep y.size() in {0;2}; run() is also { check that y in {0;0;1;1;2;2;3;3}; check that {1;1;2} in {1;2;3;4}; }; }; '>

String Matching

Example 3
This example illustrates that the order of the list items does not inuence the result of the comparison. Both checks succeed.
<' extend sys { run() is also { check that {1;2;3} in {3;2;1}; check that {1;1;2} in {1;2;1;2}; }; }; '>

See Also
List Types on page 3-11

2.9

String Matching

String matching is performed with AWK-style regular expressions. 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 . * [ \ ^ $ +? <>. For a full explanation of most of these special characters, type the following at the UNIX prompt.
% man regexp

For an explanation of the + and ? characters, type the following at the UNIX prompt.
% man egrep

2-54

Preliminary

e Language Reference Manual

String Matching

e Basics

In AWK-style regular expressions, you can also use the following Perl shorthand notations, each representing a single character. Table 2-7 Perl-style Regular Expressions Supported Meaning A shortest match operator: (back tick). Digit: [0-9] Non-digit Any white-space single char Any non-white-space single Word char: [a-zA-Z0-9_] Non-word char

Shorthand Notation ` \d \D \s \S \w \W

After doing a match, you can use the local pseudo-variables $1, $2$27, which correspond to the parenthesized pieces of the match. $0 stores the whole matched piece of the string.

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

Example 2
AWK-style matching is longest match. e 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 TRUE Prints " x " Matches x x y Prints TRUE Prints " x y "Matches x x y y

e Language Reference Manual

Preliminary

2-55

e Basics

Extraction and Concatenation Operators

Example 3
After doing a match, you can use the local pseudo-variables $1, $2$27, which correspond to the parenthesized pieces of the match. For instance:
m() is { var x := "pp--kkk"; if x ~ "/^(p*)--(k*)$/" then {print $1, $2;}; };

See Also
The String Type on page 3-13 String Routines on page 4-57 in e Libraries List Types on page 3-11

2.10 Extraction and Concatenation Operators


The following sections describe the e extraction and concatenation operators: [ ] on page 2-56 [ : ] on page 2-58 [ .. ] on page 2-61 [ range,...] on page 2-66 { ; } on page 2-63 %{} on page 2-64 Extracts or sets a single item from a list. Extracts or sets consecutive bits or slices of a scalar, a list of bits, or a list of bytes. List slicing operator Range list operator List concatenation Bit concatenation

2.10.1
Purpose

[]

List index operator

Category
Expression

2-56

Preliminary

e Language Reference Manual

[]

e Basics

Syntax
list-exp[exp] Syntax example:
ints[size] = 8;

Parameters
list-exp exp An expression that returns a list. A numeric expression.

Description
Extracts or sets a single item from a list.

Notes
Indexing is only allowed for lists. To get a single bit from a scalar, use bit extraction.
See [ : ] on page 2-58.

Checking list boundaries to see if the specied element exists is done only in interpretive
mode.

Example
<' 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]; }; }; '>

See Also
List Types on page 3-11 Chapter 3, List Pseudo-Methods in e Libraries
e Language Reference Manual
Preliminary 2-57

e Basics

[:]

2.10.2
Purpose

[:]

Select bits or bit slices of an expression

Category
Expression

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

Parameters
exp high A numeric expression, an HDL pathname, or an expression returning a list of bit or a list of byte. 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. A non-negative numeric expression, less than or equal to the high expression. A numeric expression. The default is bit.

low slice

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 specied 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 specied bits of a scalar, a list of bits, or a list of bytes.

2-58

Preliminary

e Language Reference Manual

[:]

e Basics

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 rst 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.
var big_i: int (bits: 64) = 0xffff1000ffff1000; print big_i[1:0:byte]; print big_i[1:1:int];

Accessing Nonexistent Bits If the expression is a numeric expression or an HDL pathname, any reference to a non-existent bit is not legal. However, for unbounded integers, all bits logically exist and will be 0 for positive numbers, 1 for negative numbers. When extracting nonexisting bits from list items, zeros are returned. 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;

e Language Reference Manual

Preliminary

2-59

e Basics
print x; x[2:1:byte] = 0x1234; print x;

[:]

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;

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;

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;

See Also
Bit Slice Operator and Packing on page 16-23 'HDL-pathname' on page 15-28 List Types on page 3-11 Scalar Types on page 3-2

2-60

Preliminary

e Language Reference Manual

[ .. ]

e Basics

2.10.3
Purpose

[ .. ]

List slicing operator

Category
Expression

Syntax
exp[[low]..[high]] Syntax example:
size: int [0..15];

Parameters
exp low-exp high-exp An expression returning a list or a scalar. An expression evaluating to a positive integer. The default is 0. An expression evaluating to a positive integer. The default is the expression size on bits - 1.

Description
Accesses the specied 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.

Notes
This operator cannot be used on the left-hand-side of the assignment operator. This operator is not supported for unbounded integers. Accessing non-existent elements is illegal.

e Language Reference Manual

Preliminary

2-61

e Basics

[ .. ]

Example 1
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]; m() is { print packets[5..]; print ints[0..size]; }; }; '>

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

See Also
'HDL-pathname' on page 15-28 List Types on page 3-11 Scalar Types on page 3-2

2-62

Preliminary

e Language Reference Manual

{;}

e Basics

2.10.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};

The type is derived from the rst 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};

Example
<' type color:[red, orange, yellow, green, blue, purple]; extend sys { m() is {

e Language Reference Manual

Preliminary

2-63

e Basics
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; }; }; '>

%{}

See Also
List Types on page 3-11

2.10.5
Purpose

%{}

Bit concatenation operator

Category
Expression

Syntax
%{exp1, exp2, } Syntax example:
num1 = %{num2, num3}; %{num2, num3} = num1;

Parameters
exp1, exp2 Expressions that receive lists of bits (when on the left-hand side of an assignment operator), or supply lists of bits (when on the right-hand side of an assignment operator).

Description
Creates a list of bits from two or more expressions, or creates two or more smaller lists of bits from a given expression.
2-64 Preliminary

e Language Reference Manual

%{}

e Basics

You can use the bit concatenation operator %{} for packing or unpacking operations that require the packing.high order. value-exp = %{exp1, exp2,} is equivalent to value-exp = pack(packing.high, exp1, exp2, ...). %{exp1, exp2,} = value-exp is equivalent to unpack(packing.high, value-exp, exp1, exp2, ...). Bit concatenations are untyped expressions. In many cases, the required type can be deduced from the context of the expression. See Untyped Expressions on page 3-13 for more information.

Example
This example shows several uses of the bit concatenation operator.
extend sys { 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; 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; }; };

See Also
pack() on page 4-38 in e Libraries
e Language Reference Manual
Preliminary 2-65

e Basics

Scalar Modifiers

unpack() on page 4-42 in e Libraries swap() on page 4-47 in e Libraries do_pack() on page 4-49 in e Libraries do_unpack() on page 4-53 in e Libraries

2.11 Scalar Modifiers


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

[ range,...] on page 2-66 (bits | bytes : width-exp) on page 2-67

See Also
Scalar Types on page 3-2 type sized scalar on page 3-28 type scalar subtype on page 3-26

2.11.1
Purpose

[ range,...]

Range modier

Category
Expression

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

2-66

Preliminary

e Language Reference Manual

(bits | bytes : width-exp)

e Basics

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
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]; }; '>

See Also
Scalar Subtypes on page 3-3 type scalar subtype on page 3-26

2.11.2
Purpose

(bits | bytes : width-exp)

Dene a sized scalar

Category
Expression

e Language Reference Manual

Preliminary

2-67

e Basics

Parentheses

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
Denes 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);

See Also
Scalar Types on page 3-2 type sized scalar on page 3-28

2.12 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 denitions, 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:
2-68 Preliminary

e Language Reference Manual

list.list-method()

e Basics

list.list-method() on page 2-69 Calling Predened Routines on page 4-142 in e Libraries Invoking Methods on page 6-18

2.12.1
Purpose

list.list-method()

Execute list pseudo-method

Category
Expression

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

Description
Executes a list pseudo-method on the specied 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.

Parameters
list-exp list-method An expression that returns a list. One of the list pseudo-methods described in Chapter 3, List Pseudo-Methods in e Libraries

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.

e Language Reference Manual

Preliminary

2-69

e Basics
<' extend sys { my_list: list of int; run() is also { print me.my_list.is_empty(); check that (me.my_list.size() > 5) }; }; '>

list.list-method()

Example 2
List method calls can be nested within any expression as long as the returned type matches the context. The following example lters 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; }; extend sys { packets[10]: list of packet; run() is also { print packets.all(.kind==ethernet).sort(.size); }; }; '>

See Also
Chapter 3, List Pseudo-Methods in e Libraries Implicit Variables on page 2-24

2-70

Preliminary

e Language Reference Manual

Special-Purpose Operators

e Basics

2.13 Special-Purpose Operators


e supports the following special purpose operators: is [not] a on page 2-71 Identify the subtype of a struct instance new on page 2-73 . on page 2-75 ' on page 2-77 ? : on page 2-78 Allocate a new struct Refer to elds in structs Used in names of e entities Conditional operator

2.13.1
Purpose

is [not] a

Identify the subtype of a struct instance

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; };

e Language Reference Manual

Preliminary

2-71

e Basics

is [not] a

Parameters
struct-exp subtype name An expression that returns a struct. A subtype of the specied struct type. The name of the local variable you want to create. This parameter cannot be used with is not a expressions.

Description
Identies whether a struct instance is a particular subtype or not at run time. If a name is specied, 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
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.

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; }; '> 2-72 Preliminary

e Language Reference Manual

new

e Basics

See Also
as_a() on page 4-25 in e Libraries

2.13.2
Purpose

new

Allocate a new initialized struct

Category
Expression

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

Parameters
struct-type name Either a struct type or a struct subtype. An optional name, valid within the action block, for the new struct. If no name is specied, you can use the implicit variable it to refer to the new struct. A list of one or more actions.

action

Description
Creates a new struct: 1. Allocates space for the struct. 2. Assigns default values to struct elds. 3. Invokes the init() method for the struct. 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.
e Language Reference Manual
Preliminary 2-73

e Basics

new

5. Executes the action-block, if one is specied. If no subtype is specied, 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 optional with clause is used, you can refer to the newly created struct either with the implicit variable it, or with an optional name.

Note
The new struct is a shallow struct. The elds 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; }; }; }; '>

See Also
init() on page 2-7 in e Libraries run() on page 2-10 in e Libraries Struct Subtypes on page 3-7

2-74

Preliminary

e Language Reference Manual

e Basics

2.13.3
Purpose

Refer to elds in structs

Category
Expression

Syntax
[[struct-exp].] eld-name Syntax example:
keep soft port.sender.cell.u == 0xff;

Parameters
struct-exp eld-name An expression that returns a struct. The name of the scalar eld or list eld to reference.

Description
Refers to a eld in the specied 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 eld name is resolved according to the name resolution rules.

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 eld name is a list item, the expression returns a concatenation of the lists in
the eld.

Example 1
The following example shows the use of the . to identify the elds u and kind in the keep constraints:
e Language Reference Manual
Preliminary 2-75

e Basics
<' 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 elds in a list (switch.port) and to access a eld that is a list (switch.port.data):
<' struct switch { port: list of port_stub; keep soft port.size() == 4; }; struct port_stub { data[5]: list of byte; };

2-76

Preliminary

e Language Reference Manual

'
extend sys { switch : switch; run() is also { print switch.port; print switch.port.data; }; }; '>

e Basics

See Also
Struct Hierarchy and Name Resolution on page 2-19

2.13.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 denes its purpose. A single apostrophe is used in the following places:

When accessing HDL objects (for example: 'top.a') When dening the name of a syntactic construct in a macro denition (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
Struct Subtypes on page 3-7 Enumerated Type Values on page 2-23 Code Segments on page 2-2

e Language Reference Manual

Preliminary

2-77

e Basics

?:

2.13.5
Purpose

?:

Conditional operator

Category
Expression

Syntax
bool-exp ? exp1 : exp2 Syntax example:
z = (flag ? 7 : 15);

Parameters
bool-exp exp1, exp2 A legal e expression that evaluates to TRUE or FALSE. 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 rst expression is evaluated. If it is FALSE, then the second expression is evaluated.

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

2-78

Preliminary

e Language Reference Manual

?:

e Basics

See Also
Conditional Actions on page 8-1

e Language Reference Manual

Preliminary

2-79

e Basics

?:

2-80

Preliminary

e Language Reference Manual

Data Types

The e language has a number of predened 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 external tools. The e language also provides a powerful mechanism for dening object-oriented hierarchical data structures (structs) and ordered collections of elements of the same type (lists).

See Also
Overview of e Data Types on page 3-1 Dening and Extending Scalar Types on page 3-24 Type-Related Constructs on page 4-25 in e Libraries Chapter 4, Structs, Fields and Subtypes Chapter 2, e Basics

3.1

Overview of e Data Types

The following sections provide a basic explanation of e data types:

e Data Types on page 3-2 Untyped Expressions on page 3-13

e Language Reference Manual

Preliminary

3-1

Data Types

e Data Types

Assignment Rules on page 3-16 Precision Rules for Operations on page 3-21 Automatic Type Casting on page 3-22

3.1.1

e Data Types

Most e expressions have an explicit data type. These data types are described in the following sections:

Scalar Types on page 3-2 Scalar Subtypes on page 3-3 Enumerated Scalar Types on page 3-5 Struct Types on page 3-6 Struct Subtypes on page 3-7 List Types on page 3-11 The String Type on page 3-13
Certain expressions, such as HDL objects, have no explicit data type. See Untyped Expressions on page 3-13 for information on how these expressions are handled.

3.1.1.1

Scalar Types

Scalar types in e are one of the following:

Numeric Boolean Enumerated

3-2

Preliminary

e Language Reference Manual

e Data Types

Data Types

Table 3-1 on page 3-3 shows es predened numeric and Boolean types. See the notes below the table for important information about these predened types. Table 3-1 es Predened Scalar Types Type Name int Function Represents numeric data, both negative and non-negative integers. Represents unsigned numeric data, non-negative integers only. An unsigned integer in the range 01. An unsigned integer in the range 0255. An unsigned integer in the range 0263-1. Represents truth (logical) values, TRUE(1) and FALSE (0). Default Size for Packing 32 bits Default Value 0

uint

32 bits

bit byte time

1 bit 8 bits 64 bits

0 0 0

bool

1 bit

FALSE (0)

Note Both signed and unsigned integers can be of any size and, thus, of any range. See Scalar Subtypes on page 3-3 for information on how to specify the size and range of a scalar eld or variable explicitly. See Also

Predened constants, described in Chapter 2, e Basics Constraint Boolean expressions, described in Chapter 2, e Basics

3.1.1.2

Scalar Subtypes

You can create a scalar subtype by using a scalar modier to specify the range or bit width of a scalar type. You can also specify a name for the scalar subtype if you plan to use it repeatedly in your program. Unbounded integers are a predened scalar subtype.
e Language Reference Manual
Preliminary 3-3

Data Types

e Data Types

The following sections describe scalar modiers, named scalar subtypes, and unbounded integers in more detail. Scalar Modiers There are two types of scalar modiers that you can use together or separately to modify predened scalar types: 1. Range modiers 2. Width modiers Range modiers dene the range of values that are valid. For example, the range modier in the expression below restricts valid values to those between zero and 100 inclusive.
int [0..100]

Width modiers dene the width in bits or bytes. The width modiers in the expressions below restrict the bit width to 8.
int (bits: 8) int (bytes: 1)

You can use width and range modiers in combination.


int [0..100] (bits: 7)

Named Scalar Subtypes When you use a scalar modier 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 type enumerated scalar on page 3-24 for more information on named scalar subtypes. Unbounded Integers Unbounded integers represent arbitrarily large positive or negative numbers. Unbounded integers are specied as:
3-4 Preliminary

e Language Reference Manual

e Data Types
int (bits: *)

Data Types

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

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

Unbounded unsigned integers are not allowed, so a declaration of a type such as uint
(bits:*) is illegal. See Also

type scalar subtype on page 3-26 type sized scalar on page 3-28 extend type on page 3-30

3.1.1.3

Enumerated Scalar Types

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

These symbolic constants have associated unsigned integer values. By default, the rst name in the list is assigned the value zero. Subsequent names are assigned values based upon the maximum value of the previously dened enumerated items + 1. You can also assign explicit unsigned integer values to the symbolic constants.
var kind: [immediate = 1, register = 2];

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; the value 4 is assigned to register automatically.
var kind: [immediate = 3, register];

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

e Language Reference Manual

Preliminary

3-5

Data Types
var i_kind: instr_kind;

e Data Types

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


type packet_protocol: [];

Once the protocols that are meaningful in the program are identied you can extend the denition of the type with a statement like:
extend packet_protocol : [Ethernet, IEEE, foreign];

Enumerated types can be sized.


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

Variables or elds 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.
type instr_kind: [immediate = 1, register = 2]; var i_kind: instr_kind;

See Also

type enumerated scalar on page 3-24 extend type on page 3-30

3.1.1.4

Struct Types

Structs are the basis for constructing compound data structures. The following statement creates a struct type called packet with a eld protocol of type packet_protocol.
struct packet { protocol: packet_protocol; };

You can then use the struct type packet in any context where a type is required. For example in this statement, packet denes the type of a eld in another struct.
struct port { data_in : packet; }; 3-6 Preliminary

e Language Reference Manual

e Data Types

Data Types

You can also dene a variable using a struct type.


var data_in : packet;

The default value for a struct is NULL. See Also

Chapter 4, Structs, Fields and Subtypes var on page 7-2

3.1.1.5

Struct Subtypes

When a struct eld has a Boolean type or an enumerated type, you can dene a struct subtype for one or more of the possible values for that eld. For example, the struct packet dened below has three possible subtypes based on its protocol eld. The sys struct is extended to contain a eld 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 { p: legal Ethernet packet; };

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 eld can have the same value, you must use the following syntax to refer to the struct subtype:
value'field_name struct_type

For example, if we dene two enumerated types:


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

e Language Reference Manual

Preliminary

3-7

Data Types
type source: [a, b, c, d];

e Data Types

And add two elds to the packet struct:


dest: destination; src: source;

The syntax for referring to 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; size: int [0..1k]; data[size]: list of byte; legal: bool; dest: destination; src: source; }; extend sys { p: b'dest Ethernet 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; }; 3-8 Preliminary

e Language Reference Manual

e Data Types
}; };

Data Types

You can also use the extend, when, or like constructs to add elds, methods, or method extensions that are required for a particular subtype. For example, the extend construct shown below adds a eld 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]; 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 dened with the when construct. The following Ethernet packet subtype is exactly equivalent to the Ethernet packet subtype dened 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 dene 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 Chapter 4, Structs, Fields and Subtypes for a detailed discussion of the use of these constructs to create struct subtypes.
e Language Reference Manual
Preliminary 3-9

Data Types

e Data Types

Referencing Fields in When Constructs The example below shows how to refer to a eld 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]; 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 eld 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 eld 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.

Dene pk_inst as an IEEE packet:


3-10 Preliminary

e Language Reference Manual

e Data Types
var pk_inst: IEEE packet; pk_inst.i_val = 1;

Data Types

Use this method if you want pk_inst to always be IEEE. Note that you must either declare the variable or eld to be type IEEE packet or use the is a syntax.

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 dened just as a packet. See Also

Chapter 4, Structs, Fields and Subtypes var on page 7-2 Struct Hierarchy and Name Resolution on page 2-19 when on page 4-17 extend type on page 4-7 is [not] a on page 2-71

3.1.1.6

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

Note e does not support multi-dimensional lists (lists of lists). To create a list with sublists in it, you can create a struct to contain the sublists, and then create a list of such structs as the main list. The default value of a list is an empty list.
e Language Reference Manual
Preliminary 3-11

Data Types

e Data Types

Regular Lists The following example shows two lists, packets and all_lengths.
type packet_protocol : [Ethernet, IEEE, foreign]; struct packet { protocol: packet_protocol; len: int [0..10]; }; extend sys { packets[10] : list of packet; do_print() is { var all_lengths: list of packet'len; 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, the value of the len eld in the list of packets. In packet'len, the tick (') is used as a eld selector: the term means the len eld of a packet struct. Both packets and all_lengths have 10 elements because of the explicit size [10] specied in the packets declaration. You can only specify a list size in this manner for elds. To size lists that are variables, you have to use a keep constraint. Keyed Lists A keyed list data type is similar to hash tables or association lists found in other programming languages. The declaration below species that packets is a list of packets, and that the protocol eld in the packet type is used as the hash key.
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 predened implicit variable it.
struct person { name: string; id: int; }; struct city { persons: list(key: name) of person; 3-12 Preliminary

e Language Reference Manual

Untyped Expressions
street_names: list(key: it) of string; };

Data Types

Note The only restriction on the type of the list elements is that they cannot themselves be lists. However, they can be struct types containing elds that are lists. See Also

Chapter 4, Structs, Fields and Subtypes var on page 7-2 Packing and Unpacking Lists on page 16-10 Chapter 3, List Pseudo-Methods in e Libraries

3.1.1.7

The String Type

The predened 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 eld 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. See Also

Chapter 4, Predened Routines in e Libraries Packing and Unpacking Strings on page 16-8

3.1.2

Untyped Expressions

All e expressions have an explicit type, except for the following types of expressions:
e Language Reference Manual
Preliminary 3-13

Data Types

Untyped 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, these expressions can be converted 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. 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. The precision of the operation is determined based on the expected type and the type of the operands. See Precision Rules for Operations on page 3-21 for more information. Both 'top.a' and pack(packing.low, -4) are handled as numeric types.
3-14 Preliminary

e Language Reference Manual

Untyped Expressions
print ('top.a' + pack(packing.low, 4) == 0);

Data Types

When a pack() expression includes the parameter or the return value of a method call,
the expression takes the type and size as specied in the method declaration. The pack() expression pack(packing.low, data) creates a list of bit that is implicitly unpacked into the required type list of byte as dened 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 { %opcode : uint (bits : 3); %operand : uint (bits : 5); %address : 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)

e Language Reference Manual

Preliminary

3-15

Data Types

Assignment Rules

When the type and bit size cannot be determined from the context, the expression is automatically cast 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 specication is detected, the default width is 32 bits.
One common context where the type of an expression cannot be determined is a print statement. In the following example, the value displayed by the rst 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 16-24

3.1.3

Assignment Rules

Assignment rules dene 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 3-16 Assignment to Different but Compatible Types on page 3-18 Expected Type on page 3-21 Operand Type on page 3-21

3.1.3.1

What is an Assignment?

There are several legal ways to assign values:

Assignment actions Return actions

3-16

Preliminary

e Language Reference Manual

Assignment Rules

Data Types

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 eld sys.x.
extend sys{ x: int; m() is { sys.x = '~/top/address'; var x: int; x = sys.x + 1; }; };

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 You cannot assign values to elds during declaration in this same manner.

e Language Reference Manual

Preliminary

3-17

Data Types

Assignment Rules

3.1.3.2

Assignment to Different but Compatible Types

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

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. See Automatic Type Casting on page 3-22 for more information. See Precision Rules for Operations on page 3-21 for information on how the precision of operations involving numeric types is determined. Assignment of Boolean Types A Boolean type can only be assigned with another Boolean type.
var x: bool; x = 'top.a' >= 16;

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; 3-18 Preliminary

e Language Reference Manual

Assignment Rules

Data Types

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

To assign any scalar type (numeric, enumerated, or Boolean type) to any different scalar type, you must use the .as_a() operator. 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:


p2 = p1;

An assignment of a subtype (Ether_8023 packet):


set_cell(p);

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; run() is also { p2 = p1;

e Language Reference Manual

Preliminary

3-19

Data Types
var p: Ether_8023 packet; set_cell(p); }; set_cell(p: packet) is { p.cell = new cell_8023; }; };

Assignment Rules

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 4-25 in e Libraries for an example of how to do this. 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 }; };

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

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

See Also
Untyped Expressions on page 3-13 Precision Rules for Operations on page 3-21 Automatic Type Casting on page 3-22
3-20 Preliminary

e Language Reference Manual

Precision Rules for Operations

Data Types

3.1.4

Precision Rules for Operations

Every operation in e is performed within the context of types and is carried out either with 32-bit precision or unbounded precision. The precision with which the operation is performed is inuenced by:

The expected result type of the operation The types of the operands

3.1.4.1

Expected Type

If the expected type is larger than 32 bits, then the operation is computed in unbounded precision. If the expected type is not more than 32 bits, then the operation is computed in 32 bit precision. In the following example, because the expected type of x is a 32-bit integer, its addition operation is performed in 32 bits. On the other hand, because the expected type of y is a 48-bit integer, its addition operation is performed in unbounded precision.
extend sys { m() is { var x: int = MAX_INT + 1; print MAX_INT using dec; print x using dec; var y: int (bits: 48) = MAX_INT + 1; print y using dec; }; };

3.1.4.2

Operand Type

The precision in which an operation is performed is also inuenced by its operand types. If one or more of the operands is larger than 32 bits then the operation is computed in unbounded precision. Otherwise the operation is computed in 32 bit precision. In the assignment to x in the following example, because both 1 and MAX_INT are 32 bits wide, the addition operation is performed in 32 bit precision. In the assignment to y, on the other hand, because 48'b1 is a 48-bit integer, the addition operation is performed in unbounded precision.
extend sys { m() is { var x:= 1 + MAX_INT; print MAX_INT using dec;

e Language Reference Manual

Preliminary

3-21

Data Types
print x; var y: = 48'b1 + MAX_INT; print y using dec; }; };

Automatic Type Casting

See Also
Untyped Expressions on page 3-13 Assignment Rules on page 3-16 Automatic Type Casting on page 3-22

3.1.5

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 3-13 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;

Struct subtypes are automatically type cast to their base struct type.
type packet_protocol: [Ethernet, IEEE, foreign]; struct packet { protocol: packet_protocol; size: int [0..1k]; 3-22 Preliminary

e Language Reference Manual

Automatic Type Casting

Data Types

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 ramications 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 3-23. 2. Casting of small negative numbers (signed integers) to unsigned integers produces large positive numbers. See Example 2 on page 3-23. 3. There is no automatic casting to a reference parameter. See Parameter Passing on page 6-30 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; }; };

Example 2
m() is { var x: int = -1; var y: uint = MAX_UINT; var z: uint = 1; print x == y;

e Language Reference Manual

Preliminary

3-23

Data Types
print x > z; };

Defining and Extending Scalar Types

See Also
as_a() on page 4-25 in e Libraries Untyped Expressions on page 3-13 Assignment Rules on page 3-16 Precision Rules for Operations on page 3-21

3.2

Defining and Extending Scalar Types

You can use the following constructs to dene and extend scalar types:

type enumerated scalar on page 3-24 type scalar subtype on page 3-26 type sized scalar on page 3-28 extend type on page 3-30

3.2.1
Purpose

type enumerated scalar

Dene 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 ];

3-24

Preliminary

e Language Reference Manual

type enumerated scalar

Data Types

Parameters
enum-type-name A legal e name. The name must be different from any other predened or enumerated type name because the name space for types is global. A legal e name. Each name must be unique within the type. A unique 32-bit constant expression. Names or name-value pairs can appear in any order. By default, the rst name in the list is assigned the integer value zero. Subsequent names are assigned values based upon the maximum value of the previously dened enumerated items + 1. A positive constant expression. The valid range of values for sized enumerated scalar types is limited to the range 1 to 2n - 1, where n is the number of bits.

name exp

width-exp

Description
Denes an enumerated scalar type having the name you specify and consisting of a set of names or name-value pairs.

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 {

e Language Reference Manual

Preliminary

3-25

Data Types
kind :PacketType; set() is { kind = 'top.pkt_type'; }; };

type scalar subtype

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."); }; }; };

See Also
type scalar subtype on page 3-26 type sized scalar on page 3-28 extend type on page 3-30 Enumerated Scalar Types on page 3-5

3.2.2
Purpose

type scalar subtype

Dene a scalar subtype

3-26

Preliminary

e Language Reference Manual

type scalar subtype

Data Types

Category
Statement

Syntax
type scalar-subtype-name: scalar-type [range, ] Syntax example:
type size: int [8, 16];

Parameters
scalar-subtype-name scalar-type A unique e name. Any previously dened enumerated scalar type, any of the predened scalar types, including int, uint, bool, bit, byte, or time, or any previously dened scalar subtype. A constant expression or two constant expressions separated by two dots. All constant expressions must resolve to legal values of the named type.

range

Description
Denes a subtype of a scalar type by restricting the legal values for this subtype to the specied range.

Example 1
The integer subtype dened 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 denes the inst type, which has ve 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];

e Language Reference Manual

Preliminary

3-27

Data Types

type sized scalar

Example 3
You can omit the range list, thus renaming the full range. The rst 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
type enumerated scalar on page 3-24 type sized scalar on page 3-28 extend type on page 3-30 Scalar Subtypes on page 3-3

3.2.3
Purpose

type sized scalar

Dene a sized scalar

Category
Statement

Syntax
type sized-scalar-name: named-type (bits | bytes: exp) Syntax example:
type word :uint(bits:16); type address :uint(bytes:2);

3-28

Preliminary

e Language Reference Manual

type sized scalar

Data Types

Parameters
sized-scalar-name named-type exp A unique e name. Any previously dened enumerated type or any of the predened scalar types, including int, uint, bool, or time. 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
Denes a scalar type with a specied 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 eld, the expression's value is truncated or extended automatically to t 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 lled 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(); }; };

e Language Reference Manual

Preliminary

3-29

Data Types

extend type

See Also
type enumerated scalar on page 3-24 type scalar subtype on page 3-26 extend type on page 3-30 Assignment Rules on page 3-16 Precision Rules for Operations on page 3-21

3.2.4
Purpose

extend type

Extend an enumerated scalar type

Category
Statement

Syntax
extend enum-type-name: [name[= exp], ] Syntax example:
type PacketType :[ rx, tx, ctrl ]; extend PacketType :[ status ];

Parameters
enum-type-name name exp Any previously dened enumerated type. A legal e name. Each name must be unique within the type. A unique 32-bit constant expression. Names or name-value pairs can appear in any order. By default, the rst name in the list is assigned the integer value zero. Subsequent names are assigned values based upon the maximum value of the previously dened enumerated items + 1.

3-30

Preliminary

e Language Reference Manual

extend type

Data Types

Description
Extends the specied enumerated scalar type to include the names or name-value pairs you specify.

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 dening a protocol type and extending it as new protocols are added to the test environment. For example, you can dene a packet header without having to know what specic 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 3-24 type scalar subtype on page 3-26 type sized scalar on page 3-28
e Language Reference Manual
Preliminary 3-31

Data Types

extend type

e Data Types on page 3-2

3-32

Preliminary

e Language Reference Manual

Structs, Fields and Subtypes

The basic organization of an e program is a tree of structs. A struct is a compound type that contains data elds, procedural methods, and other members. It is the e equivalent of a class in other object-oriented languages. A base struct type can be extended by adding members. Subtypes can be created from a base struct type which inherit the base types members, and contain additional members. This chapter contains the following sections:

Structs Overview on page 4-2 Dening Structs on page 4-3 Extending Structs on page 4-7 Extending Subtypes on page 4-10 Dening Fields on page 4-12 Dening List Fields on page 4-15 Creating Subtypes with When on page 4-17 Dening Methods in Subtypes on page 4-20 Dening Attributes on page 4-21

e Language Reference Manual

Preliminary

4-1

Structs, Fields and Subtypes

Structs Overview

See Also
Syntactic Elements on page 2-10 Struct Hierarchy and Name Resolution on page 2-19 Overview of e Data Types on page 3-1 Dening and Extending Scalar Types on page 3-24 Chapter 10, Constraints Chapter 6, Methods Chapter 3, List Pseudo-Methods in e Libraries Chapter 11, Events Chapter 14, Coverage Constructs

4.1

Structs Overview

Structs are used to dene data elements and behavior of components of a test environment. A struct can hold all types of data and methods. For reusability of e code, you can add struct members or change the behavior of a previously dened struct with extend. There are two ways to implement object-oriented inheritance in e: like inheritance or when inheritance:

Like inheritance is the classical, single inheritance familiar to users of all object-oriented
languages and is specied with the like clause in new struct denitions.

When inheritance is a concept unique to e and is specied by dening subtypes with


when struct members. When inheritance provides the following advantages compared to like inheritance:

Ability to have explicit reference to the when elds Ability to have multiple, orthogonal subtypes Ability to extend the struct later
There are some language restrictions on like inheritance:

A struct with like children cannot also have a when in it.


4-2 Preliminary

e Language Reference Manual

Defining Structs

Structs, Fields and Subtypes

An event in a struct (or in its parent) cannot be overridden if the struct has like children. A time consuming method cannot be overridden or extended in a struct that has like
children. The only exception to this is if the overriding or extending is done in a different e module then the one in which the time consuming method is originally dened.

A like child cannot dene or modify a cover group whose event is dened in the parent. A struct with like children can only have the following struct members in an extension
that appears after the children were dened:

Methods that are either new or were not modied in children. Constraints that create no temporary elds (see below for a denition). Cover groups

See Also
Dening Structs on page 4-3 Extending Structs on page 4-7 Extending Subtypes on page 4-10 Dening Fields on page 4-12 Dening List Fields on page 4-15 Creating Subtypes with When on page 4-17 Dening Methods in Subtypes on page 4-20 Dening Attributes on page 4-21

4.2
4.2.1

Defining Structs struct

Purpose
Dene a data struct

e Language Reference Manual

Preliminary

4-3

Structs, Fields and Subtypes

struct

Category
Statement

Syntax
struct struct-type: struct-descriptor [like base-struct-type: struct-descriptor] { [member: struct-member; ]} Syntax example:
type packet_kind: [atm, eth]; struct packet { len: int; keep len < 256; kind: packet_kind; };

Parameters
struct-type base-struct-type member; The type of the new struct. The type of the struct from which the new struct inherits its members. The contents of the struct. The following are types of struct members:

data elds for storing data methods for procedures events for dening temporal triggers coverage groups for dening coverage points when, for specifying inheritance subtypes declarative constraints for describing relations between data
elds

on, for specifying actions to perform upon event occurrences expect, for specifying temporal behavior rules
The denition of a struct can be empty, containing no members.

4-4

Preliminary

e Language Reference Manual

struct

Structs, Fields and Subtypes

Description
Structs are used to dene 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 dened (see Creating Subtypes with When on page 4-17). The optional like clause is an inheritance directive. All struct members dened in base-struct-type are implicitly dened 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 dened in this example.
struct transaction { address: uint; data: list of uint; transform(multiple:uint) is empty; };

The transaction struct contains three members:

address eld data eld transform() empty method denition

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 eld)

A keep constraint A when conditional subtype An event denition An on member


e Language Reference Manual
Preliminary 4-5

Structs, Fields and Subtypes

struct

A cover group denition


The transform() method, dened 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 pci_transaction { 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; }; };

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 elds to its base type, and place its own constraints on elds of its base type.
type AGPModeType: [AGP_2X, AGP_4X]; struct agp_transaction like pci_transaction { block_size: uint; mode: AGPModeType; when AGP_2X agp_transaction { keep block_size == 32; }; when AGP_4X agp_transaction { keep block_size == 64; }; };

4-6

Preliminary

e Language Reference Manual

Extending Structs

Structs, Fields and Subtypes

See Also
Struct Members on page 2-12 Extending Structs on page 4-7 Extending Subtypes on page 4-10 Creating Subtypes with When on page 4-17 Chapter 3, Data Types Chapter 6, Methods Chapter 10, Constraints Chapter 11, Events Chapter 14, Coverage Constructs

4.3
4.3.1

Extending Structs extend type

Purpose
Extend an existing data struct

Category
Statement

Syntax
extend [struct-subtype: subtype-descriptor] base-struct-type: struct-descriptor { [member: struct-member; ]} Syntax example:
type packet_kind: [atm, eth]; struct packet { len: int; kind: packet_kind; };

e Language Reference Manual

Preliminary

4-7

Structs, Fields and Subtypes


extend packet { keep len < 256; };

extend type

Parameters
struct-subtype Adds struct members to the specied subtype of the base struct type only. The added struct members are known only in that subtype, not in other subtypes. The base struct type to extend. The contents of the struct. A struct member is one of the following types:

base-struct-type member;

data elds for storing data methods for procedures events for dening temporal triggers coverage groups for dening coverage points when, for specifying inheritance subtypes declarative constraints for describing relations between data
elds

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 dened struct or struct subtype. Members added to the base struct type in extensions apply to all other extensions of the same struct, except when like inheritance has been used (see Notes on page 4-8).

Notes
If like inheritance has been used on a struct type, there are limitations on how the original base struct type denition can be further extended with extend:

4-8

Preliminary

e Language Reference Manual

extend type

Structs, Fields and Subtypes

Fields cannot be added to the base struct type in extensions. A method dened in the base struct type can be extended in a struct extension only
if none of the subtypes has extended the method.

Extensions of the base struct type cannot contain when struct members.

Example 1
In the following example, a struct type named pci_transaction is dened in one module, which is then imported into another module where a eld 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; }; '>

e Language Reference Manual

Preliminary

4-9

Structs, Fields and Subtypes

Extending Subtypes

Example 2
In the following, the tx_packet struct inherits its kind eld from the packet struct denition, 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
Dening Structs on page 4-3 Extending Subtypes on page 4-10 Creating Subtypes with When on page 4-17 Chapter 3, Data Types Chapter 6, Methods Chapter 10, Constraints Chapter 11, Events Chapter 14, Coverage Constructs

4.4

Extending Subtypes

A struct subtype is an instance of the struct in which one of its elds has a particular value. For example, the packet struct dened in the following example has atm packet and eth packet subtypes, depending on whether the kind eld is atm or eth.
4-10 Preliminary

e Language Reference Manual

Extending Subtypes
type packet_kind: [atm, eth]; struct packet { len: int; kind: packet_kind; }; extend packet { keep len < 256; };

Structs, Fields and Subtypes

A struct subtype can optionally be specied with extend, so that the extension only applies to that subtype.

Example 1
The following shows a denition of a struct type named packet, an extension that adds a eld named len to the struct denition, and a second extension that adds a eld named transmit_size only to packets whose kind is transmit.
type packet_kind: [transmit, receive]; struct packet { kind: packet_kind; }; extend packet { len: int; }; extend transmit packet { transmit_size: int; };

The extend transmit packet syntax above is equivalent to:


extend packet { when transmit packet { transmit_size: int; }; };

Example 2
The packet struct denition below is extended with a Boolean eld named legal. Two additional extensions add a eld named header to the packet struct: for packets whose legal value is TRUE, the header eld gets a legal_header struct instance. For packets whose legal values is FALSE, the header eld gets a bad_header struct instance.
type packet_kind: [atm, eth];

e Language Reference Manual

Preliminary

4-11

Structs, Fields and Subtypes


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; };

Defining Fields

See Also
Dening Structs on page 4-3 Extending Structs on page 4-7 Creating Subtypes with When on page 4-17 Dening Methods in Subtypes on page 4-20

4.5
4.5.1

Defining Fields eld

Purpose
Dene a struct eld

4-12

Preliminary

e Language Reference Manual

field

Structs, Fields and Subtypes

Category
Struct member

Syntax
[!][%] eld: eld-name[: type: type] [[min-val: int .. max-val: int]] [((bits | bytes):num: int)] Syntax example:
type NetworkType: [IP=0x0800, ARP=0x8060] (bits: 16); struct header { address: uint (bits: 48); hdr_type: NetworkType; !counter: int; };

Parameters
! Denotes a eld that is not generated automatically, but is assigned a default value instead. The ! and % options can be used together, in either order. Denotes a physical eld that represents data that is to be sent to the DUT. These elds are packed automatically when the struct is packed. The ! and % options can be used together, in either order. The name of the eld being dened. The type for the eld. This can be any scalar type, string, struct, or list. If the eld name is the same as an existing type, you can omit the : type part of the eld denition. Otherwise, the type specication is required. min-val..max-val (bits | bytes: num) An optional range of values for the eld, in the form. If no range is specied, the range is the default range for the elds type. The width of the eld in bits or bytes. This syntax allows you to specify a width for the eld other than the default width. This syntax can be used for any scalar eld, even if the eld has a type with a known width.

eld type

e Language Reference Manual

Preliminary

4-13

Structs, Fields and Subtypes

field

Description
Denes a eld to hold data of a specic type. You can specify whether it is a physical eld or a virtual eld, and whether the eld is to be automatically generated. For scalar data types, you can also specify the size of the eld in bits or bytes.

Example
The struct denitions below contain several types of elds.
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; }; extend sys { packet; };

The header struct contains two physical elds:

A eld named address which is a 48-bit eld of data type uint A eld named length of data type uint
The packet struct contains:

An enumerated hdr_type eld that can be either IP or ARP A physical eld named hdr of type header, which will hold an instance of the
header struct

A Boolean is_legal eld An ungenerated uint eld named counter


The sys struct extension contains a eld for an instance of a packet struct. No type declaration is required for the packet eld in the sys extension, since the eld name is the same as the name of a type that was already dened.

4-14

Preliminary

e Language Reference Manual

Defining List Fields

Structs, Fields and Subtypes

See Also
Chapter 3, Data Types Chapter 10, Constraints Chapter 16, Packing and Unpacking list of on page 4-15

4.6
4.6.1

Defining List Fields list of

Purpose
Dene a list eld

Category
Struct member

Syntax
[!][%]name: list-name[[length: length-expression]]: list of type: list-type Syntax example:
packets: list of packet;

Parameters
! % name length type 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. The name of the list being dened. An expression that gives the initial size for the list. The type of items in the list. This can be any scalar type, string, or struct. It cannot be a list.
Preliminary 4-15

e Language Reference Manual

Structs, Fields and Subtypes

list of

Description
Denes a list of items of a specied type. An initial size can be specied for the list. The list initially contains that number of items. Even if an initial size is specied, the list size can change during the test if the list is operated on by a list method that changes the number of items. All list items are initialized to their default values when the list is created. For a generated list, the initial default values are replaced by generated values. For information about initializing list items to particular values, see Assignment of Lists on page 3-20 and Constraining Lists on page 10-2.

Example
Three list elds are dened in the struct denitions 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; };

See Also
eld on page 4-12 Expressions, in Chapter 2, e Basics Chapter 3, Data Types Chapter 10, Constraints Chapter 16, Packing and Unpacking Chapter 3, List Pseudo-Methods in e Libraries

4-16

Preliminary

e Language Reference Manual

Creating Subtypes with When

Structs, Fields and Subtypes

4.7

Creating Subtypes with When

The when struct member creates a conditional subtype of the current struct type, if a particular eld of the struct has a given value. This is called when inheritance, and is one of two techniques e 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 4-3.

4.7.1
Purpose

when

Create a subtype

Category
Struct member

Syntax
when struct-subtype: subtype-descriptor base-struct-type: struct-descriptor {member: struct-member; } Syntax example:
struct packet { len: uint; good: bool; when FALSE'good packet { pkt_msg() is { out("bad packet"); }; }; };

e Language Reference Manual

Preliminary

4-17

Structs, Fields and Subtypes

when

Parameters
struct-subtype A subtype declaration in the form type-qualier'eld-name. The type-qualier is one of the legal values for the eld named by eld-name. If the eld-name is a Boolean eld, and its value is TRUE for the subtype, you can omit type-qualier. That is, if big is a Boolean eld, big is the same as TRUEbig. The eld-name is the name of a eld in the base struct type. Only Boolean or enumerated elds can be used. If the eld type is Boolean, the type qualier must be TRUE or FALSE. If the eld type is enumerated, the qualier must be a value of the enumerated type. If the type qualier can apply to only one eld in the struct, you can omit 'eld-name. More than one type-qualier'eld-name combination can be stated, to create a subtype based on more than one eld of the base struct type. base-struct-type member The struct type of the current struct (in which the subtype is being created). Denition of a struct member for the struct subtype. One or more new struct members can be dened 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 specic elds of the base struct have particular values. For example:

If a struct type named packet has a eld 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 eld named good, two subtypes are
FALSEgood packet and TRUEgood packet. Subtypes can also be combinations of elds, such as eth TRUEgood packet and eth FALSEgood packet.

4-18

Preliminary

e Language Reference Manual

when

Structs, Fields and Subtypes

Struct members you dene in a when construct can be accessed only in the subtype, not in the base struct. This provides a way to dene 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.

Note
Once you have used like inheritance to create a subtype of a base struct type, you cannot extend the base type using when.

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 eld and the print() method apply only to packet instances that have kind values of transmit.
type packet_kind: [transmit, receive]; struct packet { kind: packet_kind; when transmit packet { length: int; print() is { out("packet length is: ", length); }; }; };

Example 2
The op1 eld in the struct denition below can have one of the enumerated reg_n type values (REG0, REG1, REG2, or REG3). The kind eld can have a value of imm or reg, and the dest eld can have a value of mm_1 or reg. The REG0'op1 subtype specication in the rst when construct creates a subtype of instances in which the op1 value is REG0. This subtype has all the instr struct elds plus a print_op1() method. The reg'kind subtype specication 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 elds plus a print_kind() method.

e Language Reference Manual

Preliminary

4-19

Structs, Fields and Subtypes

Defining Methods in Subtypes

It is necessary to add the 'kind expression in the second when construct because the dest eld can also have a value of reg, which means that reg is ambiguous without the further specication of the eld name.
type reg_n : [REG0, REG1, REG2, REG3]; struct instr { %op1: reg_n; kind: [imm, reg]; dest: [mm_1, reg]; }; extend instr { when REG0'op1 instr { print_op1() is { out("instr op1 is REG0"); }; }; when reg'kind instr { print_kind() is { out("instr kind is reg"); }; }; };

See Also
Dening Structs on page 4-3 is [not] a on page 2-71

4.8

Defining Methods in Subtypes

An abstract method is one that is declared as empty or undened in a base struct type, and then dened in one or more subtypes. A method dened 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 an abstract method is declared in a base type, each denition of the method in a subtype must have the same parameters and return type as the abstract declaration.

4-20

Preliminary

e Language Reference Manual

Defining Attributes

Structs, Fields and Subtypes

Example
In the following operation struct denition, the do_op() method is an abstract method. The ADD and SUB subtypes in the operation struct extension contain two different denitions of the method. The call to the method passes two HDL variables, 'top.op_1' and 'top.op_2', as inputs.
struct operation { opcode: [ADD, SUB]; op_result: uint; do_op(op1: uint, op2: uint): uint is undefined; run() is also { op_result = do_op('top.op_1', 'top.op_2'); }; }; extend operation { when ADD operation { do_op(op1: uint, op2: uint): uint is { return op1 + op2; }; }; when SUB operation { do_op(op1: uint, op2: uint): uint is { return op1 - op2; }; }; };

See Also
Dening Structs on page 4-3 Extending Structs on page 4-7 Extending Subtypes on page 4-10 Creating Subtypes with When on page 4-17

4.9

Defining Attributes

You can dene attributes that control how a eld behaves when it is copied or compared. These attributes are used by deep_copy(), deep_compare(), and deep_compare_physical().

e Language Reference Manual

Preliminary

4-21

Structs, Fields and Subtypes

attribute field

4.9.1
Purpose

attribute eld

Dene the behavior of a eld when copied or compared

Category
Struct member

Syntax
attribute eld-name attribute-name = exp Syntax example:
attribute channel deep_copy = reference;

Parameters
eld-name deep_copy deep_compare The name of a eld in the current struct. Controls how the eld is copied by the deep_copy() routine. Controls how the eld is compared by the deep_compare() routine. attribute-name is one of the following:

deep_compare_physical Controls how the eld is compared by the deep_compare_physical() routine. deep_all Controls how the eld is copied by the deep_copy() routine or compared by the deep_compare() or deep_compare_physical() routines. Perform a deep (recursive) copy or comparison. Perform a shallow (non-recursive) copy or comparison. Do not copy or compare.

exp is one of the following: normal reference ignore

4-22

Preliminary

e Language Reference Manual

attribute field

Structs, Fields and Subtypes

Description
Denes how a eld behaves when copied or compared. For a full description of the behavior specied by each expression, see the description of the deep_copy() on page 4-2, deep_compare() on page 4-5, or deep_compare_physical() on page 4-10 in e Libraries. The attribute construct can appear anywhere, including inside a when construct or an extend construct. To determine which attributes of a eld are valid, all extensions to a unit or a struct are scanned in the order they were loaded. If several values are specied for the same attribute of the same eld, the last attribute specication loaded is the one that is used.

Example
This example shows the effects of eld attributes on the deep_copy() and deep_compare() routines. An instance of packet, which contains three elds of type port (also a struct type), is deep copied and then deep compared. Because each of the three port elds has a different attribute, the way each eld is copied and compared is also different.
< 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;

e Language Reference Manual

Preliminary

4-23

Structs, Fields and Subtypes


var port3: port = new port; var packet1: packet = new packet with { .parent = port1; .origin = port2; .dest = port3; }; var packet2: packet = deep_copy(packet1);

attribute field

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, " 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"); 4-24 Preliminary

e Language Reference Manual

attribute field

Structs, Fields and Subtypes


out("Notice no diff for the dest field, \ attribute is ignore for deep_compare"); out(""); };

}; >

See Also
deep_copy() on page 4-2 in e Libraries deep_compare() on page 4-5 in e Libraries deep_compare_physical() on page 4-10 in e Libraries

e Language Reference Manual

Preliminary

4-25

Structs, Fields and Subtypes

attribute field

4-26

Preliminary

e Language Reference Manual

Units

This chapter describes the constructs used to dene units and explains how you can use units to implement a modular verication methodology. This chapter contains the following sections:

Units Overview on page 5-1 Dening Units and Fields of Type Unit on page 5-4

See Also
Predened Methods for Any Unit on page 2-11 in e Libraries Unit-Related Predened Methods for Any Struct on page 2-17 in e Libraries Unit-Related Predened Routines on page 4-36 in e Libraries Chapter 4, Structs, Fields and Subtypes

5.1

Units Overview

Units are the basic structural blocks for creating verication modules (verication 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 elds, 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

e Language Reference Manual

Preliminary

5-1

Units

Units Overview

unique and constant place (an e path) in the run-time data structure of an e program. Both the e path and the complete HDL path associated with a unit instance are determined before the run begins. The basic run-time data structure of an e program is a tree of unit instances whose root is sys, the only predened unit in e. Additionally there are structs that are dynamically bound to unit instances. The run-time data structure of a typical e program using units is similar to that of the XYZ_router program shown in Figure 5-1. Figure 5-1 Run-Time Data Structure of the XYZ_Router

key sys unit instance struct instance XYZ_router eld

chan0

chan1

chan2

current_packet

kind

addr

len

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 5-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.

5-2

Preliminary

e Language Reference Manual

HDL Paths and Units

Units

Figure 5-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. This ability to use relative path names to reference HDL objects allows you to freely change the combination of verication cores as the HDL design and the verication environment evolve. Regardless of where the DUT component is instantiated in the nal integration, the HDL path names in the verication environment remain valid.

See Also
HDL Paths and Units on page 5-3 Limitations on Units on page 5-4

5.1.1

HDL Paths and Units

Relative HDL paths are essential in creating a verication 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 nal integration, the HDL path names are still valid. To illustrate this, lets look at how the XYZ_router (shown in Figure 5-1 on page 5-2) is bound to the DUT router (shown in Figure 5-2 on page 5-3). 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"; };

e Language Reference Manual

Preliminary

5-3

Units

Limitations on Units

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); }; };

The full HDL path of each unit instance is determined 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 rst channel instance is top.router_i.chan0. The full path for a unit instance is used to resolve any internal HDL object references that contain relative HDL paths. By default, the do_print() method of any unit prints two predened lines as well as the user-dened elds. The predened lines display the e path and the full HDL path for that unit. The e path line contains a hyperlink to the parent unit.

5.1.2

Limitations on Units

Each unit instance has a unique and constant place (an e path) in the run-time data structure of an e program that is determined before the run begins. Thus you cannot modify the unit tree by creating unit instances during the run. The following limitations are implied by the nature of unit instances and elds of unit type:

Unit instances cannot be the object of a new action or a call to copy(). Unit instances cannot be placed on the left-hand-side of the assignment operator. List methods which 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 elds in unit instances, as well as packing or unpacking into unit instances is not recommended. Unpacking into a eld of type unit when the eld is NULL is illegal.

5.2
5-4

Defining Units and Fields of Type Unit


Preliminary

The following sections describe the constructs for dening units and elds of type unit:
e Language Reference Manual

unit

Units

unit on page 5-5 eld: unit-type is instance on page 5-9 eld: unit-type on page 5-11 eld: list of unit-type on page 5-15

5.2.1
Purpose

unit

Dene 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; check that 'data_out' == 'data_in'; }; emit data_passed; }; on packet_start { start data_checker(); }; };

e Language Reference Manual

Preliminary

5-5

Units

unit

Parameters
unit-type base-unit-type member; The type of the new unit. The type of the unit from which the new unit inherits its members. The contents of the unit. Like structs, units can have the following types of members:

data elds for storing data methods for procedures events for dening temporal triggers coverage groups for dening coverage points when, for specifying inheritance subtypes declarative constraints for describing relations between data
elds

on, for specifying actions to perform upon event occurrences expect, for specifying temporal behavior rules
Unlike structs, units can also have verilog or vhdl members. This capability lets you create HDL stub les for modular designs. The denition of a unit can be empty, containing no members.

Description
Units are the basic structural blocks for creating verication modules (verication 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 before the run begins, in the run-time data structure of an e program.

5-6

Preliminary

e Language Reference Manual

unit

Units

Because the base unit type (any_unit) is derived from the base struct type (any_struct), user-dened units have the same predened methods. In addition, units can have verilog or vhdl members and have several specialized predened 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.

Example
This example denes a unit type XYZ_router.
<' unit XYZ_router { debug_mode: bool; 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; }; };

e Language Reference Manual

Preliminary

5-7

Units
// 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"); }; 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); }; // Dont read parity yet }; event packet_out is fall('packet_valid')@pclk;

unit

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; }; 5-8 Preliminary

e Language Reference Manual

field: unit-type is instance

Units

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 \ arent synchronous"); cover log using text = "End of package transaction" is { 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 5-1 Chapter 4, Structs, Fields and Subtypes

5.2.2
Purpose

eld: unit-type is instance

Dene a unit instance eld

e Language Reference Manual

Preliminary

5-9

Units

field: unit-type is instance

Category
Unit member

Syntax
eld-name[: unit-type] is instance Syntax example:
cpu: XYZ_cpu is instance;

Parameters
eld-name unit-type The instance name being dened. The name of a unit type. If the eld name is the same as an existing type, you can omit the : unit-type part of the eld denition. Otherwise, the type specication is required.

Description
Denes a eld 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 predened unit in e. 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 run-time data structure of an e program that is determined before the run begins.

Notes
Instantiating a unit in a struct is illegal; units can only be instantiated within another unit. The do-not-generate operator (!) is not allowed with elds of type unit instance. It is not recommended to use the physical eld operator (%) with elds of type unit
instance.

Example
This example creates an instance of the XYZ_router unit type in sys.
<' 5-10 Preliminary

e Language Reference Manual

field: unit-type
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, count_only); }; }; '>

Units

See Also
Units Overview on page 5-1 eld: unit-type on page 5-11 eld: list of unit-type on page 5-15 Chapter 4, Structs, Fields and Subtypes

5.2.3
Purpose

eld: unit-type

Dene a eld of type unit

Category
Struct or unit member

Syntax
[!] eld-name[: unit-type] Syntax example:
extend XYZ_router{ !current_chan: XYZ_channel; };

e Language Reference Manual

Preliminary

5-11

Units

field: unit-type

Parameters
! eld-name unit-type Denotes an ungenerated eld. The name of the eld being dened. The name of a unit type. If the eld name is the same as an existing type, you can omit the : unit-type part of the eld denition. Otherwise, the type specication is required.

Description
Denes a eld of unit type. A eld of unit type is always either NULL or a reference to a unit instance of a specied unit type.

Notes
It is not recommended to use the physical eld operator (%) with elds of type unit.

Example
In the example below, the XYZ_router is extended with an ungenerated eld of type XYZ_channel, a unit type. It remains NULL until the mutex_checker() method is called. In this method the current_chan eld 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; }; 5-12 Preliminary

e Language Reference Manual

field: list of unit instances


}; };

Units

See Also
eld: unit-type is instance on page 5-9 eld: list of unit-type on page 5-15 Chapter 4, Structs, Fields and Subtypes

5.2.4
Purpose

eld: list of unit instances

Dene a list eld of unit instances

Category
Struct or unit member

Syntax
name:[[length]]: list of unit-type is instance Syntax example:
channels: list of XYZ_channel is instance;

Parameters
name length unit-type is instance The name of the list being dened. An expression that gives the initial size for the list. A unit type. Creates a list of unit instances.

Description
Denes a list eld of unit instances. A list of unit instances can only be created or modied before the run begins.

e Language Reference Manual

Preliminary

5-13

Units

field: list of unit instances

Notes
List operations, such as list.add() or list.pop(), that alter the list created during a run
are not allowed for lists of unit instances.

It is not recommended to use the physical eld operator (%) with lists of unit instances.

Example
This example creates a list of unit instances of type XYZ_channel in XYZ_router.
<' 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; check that '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
eld: unit-type on page 5-11 eld: unit-type is instance on page 5-9 Chapter 4, Structs, Fields and Subtypes

5-14

Preliminary

e Language Reference Manual

field: list of unit-type

Units

5.2.5
Purpose

eld: list of unit-type

Dene a list eld of type unit

Category
Struct or unit member

Syntax
[!]name[[length]]: list of unit-type Syntax example:
var currently_valid_channels: list of XYZ_channel;

Parameters
! name length unit-type Do not generate this list. The name of the list being dened. An expression that gives the initial size for the list. A unit type.

Description
Denes a list eld of type unit.

Note
It is not recommended to use the physical eld 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; };

e Language Reference Manual

Preliminary

5-15

Units

field: list of unit-type


unit XYZ_router { channels: list of XYZ_channel is instance; keep channels.size() == 3; validity_checker() is { var currently_valid_channels: list of XYZ_channel; for each in channels { if '(it).valid_in' { currently_valid_channels.add(it); }; }; print currently_valid_channels; }; }; '>

See Also
eld: unit-type on page 5-11 eld: unit-type is instance on page 5-9 Chapter 4, Structs, Fields and Subtypes

5-16

Preliminary

e Language Reference Manual

Methods

e methods are similar to C functions, Verilog tasks, and VHDL processes. An e method is an operational procedure containing actions that dene its behavior. A method can have parameters, local variables, and a return value. You can dene 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 elds of that struct instance. You can dene methods that execute within a single point of simulation time (within zero time) or methods that execute over multiple cycles. The rst type of method is referred to as a regular method. The second type is called a time consuming method or TCM. TCMs are used to synchronize processes in an e program with processes or events in the DUT. Within a single e program, multiple TCMs can execute either in sequence or concurrently, along parallel but separate threads. A TCM can also have internal branches, which are multiple action blocks executing concurrently. Methods dened in one module can later be overwritten, modied or enhanced in subsequent modules using the extend mechanism. Implementing an e method is usually done in e. However, you might want to write a C routine and convert it into an e method. You can do this by declaring an e method that is implemented in C.

See Also
Dening and Extending Methods on page 6-2 Parameter Passing on page 6-30

e Language Reference Manual

Preliminary

6-1

Methods

Defining and Extending Methods

Invoking Methods on page 6-18

6.1

Defining and Extending Methods

The following sections describe the syntax for dening and extending methods:

method is [inline] on page 6-2 method @event is on page 6-5 method [@event] is also | rst | only | inline only on page 6-9 method [@event] is undened | empty on page 6-15

6.1.1
Purpose

method is [inline]

Declare a regular method

Category
Struct member

Syntax
method-name ([parameter-list]) [: return-type] is [inline] {action;} Syntax example:
struct print { print_length() is { out("The length is: ", length); }; };

6-2

Preliminary

e Language Reference Manual

method is [inline]

Methods

Parameters
method-name parameter-list A legal e name. See Chapter 2, e Basics for more information on names. A list composed of zero or more parameter declarations of the form param-name: [*]param-type 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 2, e Basics for more information on names. * When an asterisk is prexed to a scalar parameter type, the location of the parameter, not its value, is passed. When an asterisk is prexed to a list or struct type, the method can completely replace the struct or list. See Parameter Passing on page 6-30 for more information. Species the parameter type.

param-type return-type inline action;

For methods that return values, species the data type of the return value. See Chapter 3, Data Types for more information. Denes a new inline method and allows the compiler to optimize the inline method code for the best performance. 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 2-13.

Description
Denes a new regular method that executes in a single point of time. e methods are similar to C functions, Verilog tasks, and VHDL processes. An e method is an operational procedure containing actions that dene its behavior. A method can have parameters, local variables, and a return value. You can dene 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 elds of that struct instance. Dening a method as inline requires the compiler to place all the code for the method at each point in the code where the method is called. This inline expansion allows the compiler to optimize the inline method code for the best performance. Methods that are frequently called and involve computation, such as the one shown below, are good candidates for inline denition. This method takes two integers as arguments and returns an integer:
e Language Reference Manual
Preliminary 6-3

Methods

method is [inline]
struct meth { get_free_area_size(size: int, taken: int): int is inline { result = size - taken; }; };

Notes
The following restrictions apply to all regular 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 dene 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 elds. The following restrictions apply to inline methods only:

A method originally dened as inline cannot be redened using is only, is rst, or


is also.

Inline methods cannot contain return actions; to return a value from an inline
method, use the result variable. (See Chapter 2, e Basics for information about using Implicit Variables like result.)

Methods dened in when conditional struct members cannot be inline. Time consuming methods (TCMs) cannot be inline. Methods that are directly or indirectly recursive cannot be dened as inline. You cannot set a breakpoint on an inline method when there are compiled les that
call the method.

Example
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; }; 6-4 Preliminary

e Language Reference Manual

method @event is

Methods

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; };

See Also
method @event is on page 6-5 method [@event] is also | rst | only | inline only on page 6-9 method [@event] is undened | empty on page 6-15 Invoking Methods on page 6-18 Parameter Passing on page 6-30 Chapter 2, Predened Methods in e Libraries Chapter 2, e Basics (in particular, Actions on page 2-13)

6.1.2
Purpose

method @event is

Declare a time-consuming method

Category
Struct member

Syntax
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;

e Language Reference Manual

Preliminary

6-5

Methods
}; };

method @event is

Parameters
method-name parameter-list A legal e name. See Chapter 2, e Basics for more information on names. A list composed of zero or more parameter declarations of the form param-name: [*]param-type 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 2, e Basics for more information on names. * When an asterisk is prexed to a scalar parameter type, the location of the parameter, not its value, is passed. When an asterisk is prexed to a list or struct type, the method can completely replace the struct or list. See Parameter Passing on page 6-30 for more information. Species the parameter type.

param-type return-type @event

For methods that return values, species the data type of the return value. See Chapter 3, Data Types for more information. Species a default sampling event that determines the sampling points of the TCM. This event must be a dened 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 12, Temporal Expressions for information on dening default sampling events. A list of zero or more actions, either time-consuming actions or regular actions. For information on actions, see Actions on page 2-13.

action;

Description
Denes a new time consuming method (TCM). e methods are similar to C functions, Verilog tasks, and VHDL processes. An e method is an operational procedure containing actions that dene its behavior. A method can have parameters, local variables, and a return value. You can dene 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 elds of that struct instance.
6-6 Preliminary

e Language Reference Manual

method @event is

Methods

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; };

For more information on sampling events, see Chapter 11, Events. For more information on temporal expressions, see Chapter 12, Temporal Expressions.

Notes
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.

e Language Reference Manual

Preliminary

6-7

Methods

method @event is

You cannot dene 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 elds.

Example
The init_dut TCM shown has two branches running in parallel. The rst 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 dened 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"); }; { wait [2]; all of { {check_bus_controller()}; {check_memory_controller()}; {check_alu()}; }; out("Checking is complete..."); emit mready; }; }; };

See Also
method is [inline] on page 6-2 method [@event] is also | rst | only | inline only on page 6-9 method [@event] is undened | empty on page 6-15
6-8 Preliminary

e Language Reference Manual

method [@event] is also | first | only | inline only

Methods

Invoking Methods on page 6-18 Parameter Passing on page 6-30 Chapter 12, Temporal Expressions Chapter 13, Time-Consuming Actions start tcm() on page 6-21 Semaphore Methods on page 2-31 in e Libraries event on page 11-4

6.1.3

method [@event] is also | rst | only | inline only

Purpose
Extend a regular method or a TCM

Category
Struct member

Syntax
method-name ([parameter-list]) [: return-type] [@event-type] is [also|rst|only|inline only] {action;} Syntax example:
struct meth { run() is also { out("Starting main"); start main(); }; };

e Language Reference Manual

Preliminary

6-9

Methods

method [@event] is also | first | only | inline only

Parameters
method-name parameter-list return-type @event-type also rst only inline only action; The name of the original method. Species the same parameter list as dened in the original method. Specifying a different parameter list is illegal. Species the same return value as dened in the original method. Specifying a different return value is illegal. Species the same sampling event as dened in the original method or a compile-time error is issued. The new action block is appended to the end of the original action block. The new action block is inserted before the original action block. The new action block overrides the original action block. Replaces the original method denition with an inline denition. The original method must be a regular method, not a TCM. 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 2-13.

Description
Replaces or extends the action block in the original method declaration with the specied action block. The following example extends the structs predened method run() to start a user-dened 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(); };

This example extends the init_dut() TCM to start another user-dened 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(); 6-10 Preliminary

e Language Reference Manual

method [@event] is also | first | only | inline only


}; };

Methods

Notes
Methods that were originally dened as inline cannot be extended or redened. The original method and its extensions share the me and result variables. No other local
variables can be shared across extensions.

The following rules apply for return actions in extended methods, as illustrated in
Figure 6-1 on page 6-12, Figure 6-2 on page 6-13 and Figure 6-3 on page 6-14:

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 rst, 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 6-1 on page 6-12 shows how a method with an is also extension is executed. The older version executes rst and then the is also extension. Notice that the This is also2 statement is not executed because it follows a return.

e Language Reference Manual

Preliminary

6-11

Methods

method [@event] is also | first | only | inline only

Figure 6-1

Execution of is also Method Extension

older version of method

<' struct meth { m() is { out("This is"); }; }; extend sys { mi:meth; }; extend meth { m() is also { out("This is also"); return; out("This is also2"); }; }; '> Result This is... This is also...

is also

Figure 6-2 on page 6-13 shows the same method extended again, this time with is rst. If a return statement is included in the is rst extension, the older version of the method (the original method denition and the is also extension) do not execute. If the return statement is deleted, the is rst extension executes and then the older version of the method executes.

6-12

Preliminary

e Language Reference Manual

method [@event] is also | first | only | inline only

Methods

Figure 6-2

Execution of is rst Method Extension


<' import methods12.e; extend meth { m() is first { out("This is first"); return; }; }; '> Result with a return in is rst This is first... Result with no return in is rst This is first... This is... This is also...

is rst

yes return? no older version of method

Figure 6-3 on page 6-14 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.

e Language Reference Manual

Preliminary

6-13

Methods

method [@event] is also | first | only | inline only

Figure 6-3

Execution of is rst Method Extension


<' import methods13.e; extend meth { m() is also { out("This is also3"); }; }; '>

older version of method

is also Result with a return in is rst This is first... This is also3... Result with no return in is rst This This This This is first... is... is also... is also3...

Example 1
This example redenes the increment_cnt() method as an inline method.
extend meth { increment_cnt (cnt: *int) is inline only { cnt = cnt + 1; }; };

Example 2
In this example, the show() method is dened 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 { 6-14 Preliminary

e Language Reference Manual

method [@event] is undefined | empty


kind: packet_kind; has_error: bool; show() is { out("Packet kind is", kind); }; when has_error packet{ show() is only { out("This packet has an error"); }; }; };

Methods

Example 3
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.
extend ctrl_stub { execute(cmd: ctrl_cmd) @cclk is first { if ('top.interrupt' == 1) then { return; }; }; };

See Also
method is [inline] on page 6-2 method @event is on page 6-5 method [@event] is undened | empty on page 6-15

6.1.4

method [@event] is undened | empty

Purpose
Declare an abstract method
e Language Reference Manual
Preliminary 6-15

Methods

method [@event] is undefined | empty

Category
Struct member

Syntax
method-name ([parameter-list]) [: return-type] [@event-type] is [undened|empty] Syntax example:
struct packet { show() is undefined; };

Parameters
method-name parameter-list A legal e name. See Chapter 2, e Basics for more information on names. A list composed of zero or more parameter declarations of the form param-name: [*]param-type 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 2, e Basics for more information on names. When an asterisk is prexed to a scalar parameter type, the location of the parameter, not its value, is passed. When an asterisk is prexed to a list or struct type, the method can completely replace the struct or list. See Parameter Passing on page 6-30 for more information. Species the parameter type.

param-type return-type

For methods that return values, species the data type of the return value. See Chapter 3, Data Types for more information.

6-16

Preliminary

e Language Reference Manual

method [@event] is undefined | empty

Methods

@event-type

Species a default sampling event that determines the sampling points of the TCM. This event must be a dened 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. No action block is dened for the method yet; an action block must be dened in a subsequent module before this method is called. Calling the method before it is dened is illegal. The action block is empty; however, calling the method before it is dened is legal. Empty value-returning methods return the default value for the type.

undened

empty

Description
Declares an abstract regular method or an abstract TCM with no dened 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:

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 dene 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 elds.

Example
Undened or empty methods are often used in base types. This example declares an abstract method show() in the base struct packet and denes the appropriate functionality in the Ethernet packet and IEEE packet subtypes.
type packet_protocol: [Ethernet, IEEE, foreign]; struct packet { protocol: packet_protocol; size: int [0..1k];

e Language Reference Manual

Preliminary

6-17

Methods
data[size]: list of byte; show() is undefined; }; extend Ethernet packet { e_field: int;

Invoking Methods

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 { a.show(); b.show(); c.show(); }; };

See Also
method is [inline] on page 6-2 method @event is on page 6-5 method [@event] is also | rst | only | inline only on page 6-9

6.2

Invoking Methods

Before invoking a method, you must create an instance of the struct that contains it. The call must conform to the proper syntax and must be made from an appropriate context, as described below. The following sections describe the two ways to invoke a TCM:

tcm() on page 6-19


6-18 Preliminary

e Language Reference Manual

tcm()

Methods

start tcm() on page 6-21


The following sections describe how you can call regular methods:

method() on page 6-23 compute method() on page 6-25


The last section describes the return action:

return on page 6-27

See Also
Dening and Extending Methods on page 6-2 Parameter Passing on page 6-30

6.2.1
Purpose

tcm()

Call a TCM

Category
Action or expression

Syntax
[[struct-exp].]method-name([parameter-list]) Syntax example:
init_dut();

e Language Reference Manual

Preliminary

6-19

Methods

tcm()

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 2, e Basics for more information on naming resolution. The method name as specied in the method denition. A list of zero or more parameters separated by commas, one parameter for each parameter in the parameter list of the method denition. 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 method denition. The parentheses around the parameter list are required even if the parameter list is empty.

method-name parameter-list

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 6-21) 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 eld 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 time slot. 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.

Note
You cannot call a TCM from a regular method. To invoke a TCM from within a regular method, use start.

Example
This example shows how to call a TCM from another TCM.
struct meth { 6-20 Preliminary

e Language Reference Manual

start tcm()
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; }; };

Methods

See Also
start tcm() on page 6-21 Chapter 13, Time-Consuming Actions Struct Hierarchy and Name Resolution on page 2-19 Invoking Methods on page 6-18 Dening and Extending Methods on page 6-2 Parameter Passing on page 6-30

6.2.2
Purpose

start tcm()

Start a TCM

Category
Action

Syntax
start [[struct-exp].]method-name([parameter-list]) Syntax example:
start main();

e Language Reference Manual

Preliminary

6-21

Methods

start tcm()

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 2, e Basics for more information on naming resolution. The method name as specied in the method denition. A list of zero or more parameters separated by commas, one parameter for each parameter in the parameter list of the method denition. 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 method denition. The parentheses around the parameter list are required even if the parameter list is empty.

method-name parameter-list

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 time slot. 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 predened methods of the scheduler. The recommended way to start an initial TCM, which can then invoke other TCMs, is to extend the related structs predened run() method.

Notes
A TCM that has a return value cannot be started with a start action.

Example
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(); 6-22 Preliminary

e Language Reference Manual

method()
}; };

Methods

See Also
run() on page 2-10 in e Libraries Chapter 13, Time-Consuming Actions Struct Hierarchy and Name Resolution on page 2-19 Invoking Methods on page 6-18 Dening and Extending Methods on page 6-2 Parameter Passing on page 6-30

6.2.3
Purpose

method()

Call a regular method

Category
Action or expression

Syntax
[[struct-exp].]method-name([parameter-list]) Syntax example:
tmp1 = get_free_area_size(size, taken);

e Language Reference Manual

Preliminary

6-23

Methods

method()

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 2, e Basics, for more information about naming resolution. The method name as specied in the method denition. A list of zero or more parameters separated by commas, one parameter for each parameter in the parameter list of the method denition. 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 method denition. The parentheses around the parameter list are required even if the parameter list is empty.

method-name parameter-list

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.

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 eld it is assigned to.

6-24

Preliminary

e Language Reference Manual

compute method()

Methods

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, 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 6-25 Struct Hierarchy and Name Resolution on page 2-19 Dening and Extending Methods on page 6-2 Parameter Passing on page 6-30

6.2.4
Purpose

compute method()

Compute a regular method


e Language Reference Manual
Preliminary 6-25

Methods

compute 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 2, e Basics, for more information about naming resolution. The method name as specied in the method denition. A list of zero or more parameters separated by commas, one parameter for each parameter in the parameter list of the method denition. 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 method denition. The parentheses around the parameter list are required even if the parameter list is empty.

method-name parameter-list

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.

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();}; 6-26 Preliminary

e Language Reference Manual

return
};

Methods

See Also
method() on page 6-23 Struct Hierarchy and Name Resolution on page 2-19 Dening and Extending Methods on page 6-2 Parameter Passing on page 6-30

6.2.5
Purpose

return

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.

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 or result statement. A method can simply be allowed to reach its end and return to the caller.
e Language Reference Manual
Preliminary 6-27

Methods

return

Notes
The return action must be used carefully in method extensions. See method [@event]
is also | rst | only | inline only on page 6-9 for more information.

Any actions that follow a return action in the method denition 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"); }; }; '>

6-28

Preliminary

e Language Reference Manual

return

Methods

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 denition 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"); }; }; '>

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 eld.

e Language Reference Manual

Preliminary

6-29

Methods

Parameter Passing

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"; }; }; 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; }; }; '>

"a3"}; "b3"}; "c3"}; "d3"}; "e3"};

}; }; }; }; };

See Also
method [@event] is also | rst | only | inline only on page 6-9

6.3

Parameter Passing

How a parameter is passed depends on whether the parameter is scalar or compound, as described in these sections:
6-30 Preliminary

e Language Reference Manual

Scalar Parameter Passing

Methods

Scalar Parameter Passing on page 6-31 Compound Parameter Passing on page 6-31

6.3.1

Scalar Parameter Passing

Scalar parameters include numeric, Boolean, and enumerated types. When you pass a scalar parameter to a method, by default the value of the parameter is passed. This is called passing by value. Any change to the value of that parameter by the method applies only within that method instance and is lost when the method returns. For example, the increment() method dened below increments the value of the parameter passed to it.
increment (cnt: int) is { cnt = cnt + 1; }; m() is { var tmp: int = 7; increment(tmp); print tmp; };

However, since cnt is passed by value, the variable tmp retains its original value, and the print statement displays:
tmp = 7

To allow a method to modify the parameter, prex the parameter type with an asterisk. This is called passing by reference. If you modify the increment() method as follows:
increment (cnt: *int) is { cnt = cnt + 1; }; m() is { var tmp: int = 7; increment(tmp); print tmp; };

tmp has the value 8 after the method returns. Note that the asterisk is used only in the method denition, not in the method call.

6.3.2

Compound Parameter Passing

Compound parameters are either structs or lists. Passing a struct or a list to a method allows the method to modify the struct elds and the list items. This is called passing by reference. Thus, if you modify the increment() method to accept a list:
e Language Reference Manual
Preliminary 6-31

Methods
increment_list (cnt: list of int) is { for each in cnt { cnt[index] = cnt[index] + 1; }; };

Notes on Passing by Reference

and pass a list of integers to it, each item in the list reects its incremented value after the method returns. Placing an asterisk in front of the list or struct type allows the method to completely replace the struct or list. For example, the create_if_illegal() method accepts a struct instance of type packet. If it determines that the legal eld of struct instance is FALSE, it allocates a new struct instance of type packet.
create_if_illegal(pkt: *packet) is { if pkt.legal == FALSE then { pkt = new; }; };

6.3.3

Notes on Passing by Reference

There are several restrictions that apply when you pass parameters by reference:

There is no automatic casting to a reference parameter. You cannot pass a list element by reference. An expression that cannot be placed on the left-hand-side of an assignment cannot be
passed by reference.

Called TCMs can accept reference parameters, but started TCMs cannot.

6-32

Preliminary

e Language Reference Manual

Creating and Modifying e Variables

The following sections describe how to create and assign values to e variables:

About e Variables on page 7-1 var on page 7-2 = on page 7-4 op= on page 7-6

7.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 2-19 in the e Language Reference. Some e actions create implicit variables. They are described in more detail in Implicit Variables on page 2-24 in the e Language Reference The following sections describe the actions that create and modify e variables explicitly.
e Language Reference Manual
Preliminary 7-1

Creating and Modifying e Variables

var

var on page 7-2 = on page 7-4 op= on page 7-6

7.2
Title

var

Variable denition

Category
Action

Syntax
var name : [[list of] type] [= exp] Syntax example:
var a: int;

Parameters
name type exp A legal e name. 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. The initial value of the variable. If no initial value is specied, the variables are initialized to 0 for integer types, NULL for structs, FALSE for Boolean types, and lists as empty.

Description
Denes a new variable with the specied name as an element or list of elements of the specied 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.

7-2

Preliminary

e Language Reference Manual

var

Creating and Modifying e Variables

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 2-19 in the e Language Reference.

Example 1
These examples show the declaration of two variables, one with an assigned initial value:
<' 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 examples 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];

e Language Reference Manual

Preliminary

7-3

Creating and Modifying e Variables


data[len]: list of byte; }; extend sys { m() is { var packet; }; }; '>

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; }; }; '>

7.3

Purpose
Simple assignment

Category
Action

Syntax
lhs-exp=exp Syntax example:
sys.u = 0x2345;

7-4

Preliminary

e Language Reference Manual

Creating and Modifying e Variables

Parameters
lhs-exp A legal e expression that evaluates to a variable of a method, a global variable, a eld 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 %{}. 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.

exp

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;

e Language Reference Manual

Preliminary

7-5

Creating and Modifying e Variables


}; '>

op=

Example 2
This example shows the assignment operator used in initialization.
<' 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; }; }; }; '>

See Also
Untyped Expressions on page 3-13 Assignment Rules on page 3-16 Precision Rules for Operations on page 3-21 Automatic Type Casting on page 3-22

7.4

op=

Purpose
Compound assignment

7-6

Preliminary

e Language Reference Manual

op=

Creating and Modifying e Variables

Category
Action

Syntax
lhs-exp op=exp Syntax example:
sys.c.count1 += 5;

Parameters
lhs-exp exp op A legal e expression that evaluates to a variable of a method, a global variable, a eld of a struct, or an HDL object. A legal e expression of the same type as the left-hand-side expression. A binary operator, including binary bitwise operators (except ~), the Boolean operators and and or, and the binary arithmetic operators.

Description
Performs the specied 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;

e Language Reference Manual

Preliminary

7-7

Creating and Modifying e Variables


print sys.c.count1, sys.c.mult; }; }; '>

op=

Example 2
This example shows the compound assignment operator used with the shift operator.
<' extend sys { m() is { print 'top.address'; 'top.address' <<= 4; print 'top.address'; }; }; '>

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; }; }; '>

7-8

Preliminary

e Language Reference Manual

Control Flow Actions

The following sections describe the control ow actions:

Conditional Actions on page 8-1 Iterative Actions on page 8-7 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

8.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 8-2 case labeled-case-item on page 8-3 case bool-case-item on page 8-5

e Language Reference Manual

Preliminary

8-1

Control Flow Actions

if then else

8.1.1
Purpose

if then else

Perform an action block based on whether a given Boolean expression is TRUE

Category
Action

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 action; ... A Boolean expression. A series of zero or more actions separated by semicolons and enclosed in curly braces.

Description
If the rst bool-exp is TRUE, the then action block is executed. If the rst 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 nal 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.
8-2 Preliminary

e Language Reference Manual

case labeled-case-item

Control Flow Actions

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:
if a_ok { print x; } else if b_ok { print y; } else { print z; };

See Also
case labeled-case-item on page 8-3 case labeled-case-item on page 8-3 Iterative Actions on page 8-7 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

8.1.2
Purpose

case labeled-case-item

Execute an action block based on whether a given comparison is true

e Language Reference Manual

Preliminary

8-3

Control Flow Actions

case labeled-case-item

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")}; [256..512]: {out("long packet")}; default: {out("illegal packet length")}; };

Parameters
case-exp labeled-case-item A legal e expression. label-exp[:] action-block Where

label-exp is a value or a range action-block is a list of zero or more actions separated by


semicolons and enclosed in curly braces. Syntax: {action;} Note that 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 rst action-block for which label-exp matches the case-exp. If no label-exp equals the case-exp, executes the default-action block, if specied. After an action-block is executed, execution proceeds to the line that immediately follows the entire case statement.

8-4

Preliminary

e Language Reference Manual

case bool-case-item

Control Flow Actions

Example
struct m { counter: uint; kind: [small, medium, large, xlarge, xxlarge]; c_meth() is { case me.kind { small: {print "SMALL"}; [large, medium]: { print "LARGE or MEDIUM"; me.counter += 1; }; default: {print "OTHER"}; }; }; };

See Also
if then else on page 8-2 case bool-case-item on page 8-5 Iterative Actions on page 8-7 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

8.1.3
Purpose

case bool-case-item

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:

e Language Reference Manual

Preliminary

8-5

Control Flow Actions


case { packet.length == 64 packet.length in [65..255] default };

case bool-case-item

{out("minimal packet"); }; {out("short packet"); }; {out("illegal packet"); };

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. 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 rst TRUE bool-exp. If no bool-exp is TRUE, executes the default-action-block, if specied. After an action-block is executed, execution 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 8-3). 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 elds and attributes (not only to a single eld as in the example above). For example, here is a set of independent Boolean conditions:
8-6 Preliminary

e Language Reference Manual

Iterative Actions

Control Flow Actions

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; 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 8-2 case labeled-case-item on page 8-3 Iterative Actions on page 8-7 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

8.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 8-8 repeat until on page 8-10 for each in on page 8-11 for from to on page 8-14 for on page 8-15

e Language Reference Manual

Preliminary

8-7

Control Flow Actions

while

8.2.1
Purpose

while

Execute a while loop

Category
Action

Syntax
while bool-exp [do] {action; ...} Syntax example:
while a < b {a += 1;};

Parameters
bool-exp action; ... A Boolean expression. 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.
8-8 Preliminary

e Language Reference Manual

while
lp_read()@clk is { while (!done) { wait [2]*cycle; ctr = top.inc; }; };

Control Flow Actions

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 8-10 for each in on page 8-11 for from to on page 8-14 for on page 8-15 Conditional Actions on page 8-1 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

e Language Reference Manual

Preliminary

8-9

Control Flow Actions

repeat until

8.2.2
Purpose

repeat until

Execute a repeat until loop

Category
Action

Syntax
repeat {action; ...} until bool-exp Syntax example:
repeat {i+=1;} until i==3;

Parameters
action; ... bool-exp A sequence of zero or more actions separated by semicolons and enclosed in curly braces. 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;

8-10

Preliminary

e Language Reference Manual

for each in

Control Flow Actions

See Also
while on page 8-8 for each in on page 8-11 for from to on page 8-14 for on page 8-15 Conditional Actions on page 8-1 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

8.2.3
Purpose

for each in

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

e Language Reference Manual

Preliminary

8-11

Control Flow Actions

for each in

Parameters
type item-name A type of the struct comprising the list specied by list-exp. Elements in the list must match this type to be acted upon. 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. We recommend 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. We recommend that you explicitly name the item to avoid confusion about the contents of index. list-exp action; ... An expression that results in a list. A sequence of zero or more actions separated by semicolons and enclosed in curly braces.

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) reects the index of the current item. If reverse is specied, list-exp is traversed in reverse order, from last to rst. 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 denes 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 { 8-12 Preliminary

e Language Reference Manual

for each in
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(); }; }; '>

Control Flow Actions

Example 2
for each in reverse pktList do { // Traverse in reverse order print it; // "it" can refer to the various subtypes };

See Also
while on page 8-8 repeat until on page 8-10 for from to on page 8-14 for on page 8-15 Implicit Variables on page 2-24 Conditional Actions on page 8-1 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

e Language Reference Manual

Preliminary

8-13

Control Flow Actions

for from to

8.2.4
Purpose

for from to

Execute a for loop for the number of times specied 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 from-exp, to-exp, step-exp action; ... A temporary variable of type int. Valid e expressions that resolve to type int. The default value for step-exp is one. 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 specied) its value from from-exp to to-exp in interval values specied 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. For example, the following line of code prints in one time:
for j from 1 to 1 {out("in");};

Note
The temporary variable var-name is visible only within the for from to loop in which it is created.
8-14 Preliminary

e Language Reference Manual

for

Control Flow Actions

Example
for i from 2 to 2 * a do { out(i); }; for i from 1 to 4 step 2 do { 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 8-8 repeat until on page 8-10 for each in on page 8-11 for on page 8-15 Conditional Actions on page 8-1 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

8.2.5
Purpose

for

Execute a C-style for loop

Category
Action

Syntax
for {initial-action; bool-exp; step-action} [do] {action; ...} Syntax example:

e Language Reference Manual

Preliminary

8-15

Control Flow Actions


for {i=0; i<=10; i+=1} do {out(i);};

for

Parameters
initial-action bool-exp step-action action; ... An action. A Boolean expression An 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; 8-16 Preliminary

e Language Reference Manual

File Iteration Actions


}; };

Control Flow Actions

See Also
while on page 8-8 repeat until on page 8-10 for each in on page 8-11 for from to on page 8-14 Conditional Actions on page 8-1 File Iteration Actions on page 8-17 Actions for Controlling the Program Flow on page 8-20

8.3

File Iteration Actions

This section describes the following two loop constructs, which are used to manipulate general ASCII les:

for each line in le on page 8-17 for each le matching on page 8-18

8.3.1
Purpose

for each line in le

Iterate a for loop over all lines in a text le

Category
Action

Syntax
for each [line] [(name)] in le le-name-exp [do] {action; } Syntax example:
e Language Reference Manual
Preliminary 8-17

Control Flow Actions

for each file matching

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 le-name-exp action; ... Variable referring to the current line in the le. A string expression that gives the name of a text le. 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 le le-name. Inside the block, it (or optional name) refers to the current line (as string) without the nal \n (the nal new line character, CR).

Example
for each line (l) in file "test.dat" { // Print all the nonblank lines in the file if l !~ "/^$/" then { print l; }; };

See Also
for each le matching on page 8-18 Conditional Actions on page 8-1 Iterative Actions on page 8-7 Actions for Controlling the Program Flow on page 8-20

8.3.2
Purpose

for each le matching

Iterate a for loop over a group of les

8-18

Preliminary

e Language Reference Manual

for each file matching

Control Flow Actions

Category
Action

Syntax
for each le [(name)] matching le-name-exp [do] {action; ...} Syntax example:
for each file matching "*.e" {out(it);} //lists the e files in the current directory

Parameters
name le-name-exp action; ... Variable referring to the current line in the le. A string expression giving a le name. A sequence of zero or more actions separated by semicolons and enclosed in curly braces.

Description
For each le (in the le search path) whose name matches le-name-exp execute the action block. Inside the block, it (or optional name) refers to the matching le 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 le on page 8-17 Conditional Actions on page 8-1 Iterative Actions on page 8-7 Actions for Controlling the Program Flow on page 8-20

e Language Reference Manual

Preliminary

8-19

Control Flow Actions

Actions for Controlling the Program Flow

8.4

Actions for Controlling the Program Flow

The actions described in this section are used to alter the ow of the program in places where the ow would otherwise continue differently. The e language provides the following actions for controlling the program ow:

break on page 8-20 continue on page 8-21

8.4.1
Purpose

break

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 rst one following the loop. You cannot place break actions outside the scope of a loop.

Example
for each (p) in packet_list do { // ... other code if p.len == 0 then { break; // Get out of this loop }; 8-20 Preliminary

e Language Reference Manual

continue
// ... other code };

Control Flow Actions

See Also
continue on page 8-21 Conditional Actions on page 8-1 Iterative Actions on page 8-7 File Iteration Actions on page 8-17

8.4.2
Purpose

continue

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. Placing continue actions outside the scope of a loop is illegal.

Example
for each (p) in packet_list do {

e Language Reference Manual

Preliminary

8-21

Control Flow Actions

continue

if p.len == 1 then { continue; // Go to next iteration, skip "print p" }; print p; };

See Also
break on page 8-20 Conditional Actions on page 8-1 Iterative Actions on page 8-7 File Iteration Actions on page 8-17

8-22

Preliminary

e Language Reference Manual

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 9-1 Handling User Errors on page 9-10 Handling Programming Errors on page 9-16

9.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 9-2 dut_error() on page 9-3 dut_error_struct on page 9-4 set_check() on page 9-8

e Language Reference Manual

Preliminary

9-1

Checks and Error Handling

check that

9.1.1
Purpose

check that

Perform a data comparison and, depending on the results, print a message

Category
Action

Syntax
check [that] bool-exp [else dut_error(error-exp, )] 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 struct members.

Parameters
bool-exp error-exp Boolean expression that performs a data comparison. String or an expression that can be converted to a string. If the bool-exp is FALSE, the error-exps are converted to strings, concatenated, and printed to the screen (and to the log le if it is open).

Description
Performs a data comparison and, depending on the results, prints a message.

Example
The following example
check_hard_error() is { check that 'top.hard_error'== 1 else dut_error("Error-5 -- Hard error not asserted"); 9-2 Preliminary

e Language Reference Manual

dut_error()
};

Checks and Error Handling

displays an error message like this one:


Error-5 -- Hard error not asserted

If you omit the else dut_error clause, the check that clause is used as the error message. This example
check_a() is { check that a < b; };

displays an error message like this one:


check that a < b

9.1.2
Purpose

dut_error()

Specify a DUT error message string

Category
Action

Syntax
dut_error(error-exp, ) Syntax example:
if 'data_out' != 'data_in' then {dut_error("DATA MISMATCH: Expected ", 'data_in')};

Parameters
error-exp String or an expression that can be converted to a string. The error-exps are converted to strings, concatenated, and printed to the screen (and to the log le if it is open).

e Language Reference Manual

Preliminary

9-3

Checks and Error Handling

dut_error_struct

Description
Species a DUT error message string. 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
Calling dut_error() directly (not within a check that or an expect), does not guarantee that a check was successfully performed.

Example
<' extend sys { m() is { if 'data_out' != 'data_in' then {dut_error("DATA MISMATCH: Expected ", 'data_in')}; }; }; '>

9.1.3
Purpose

dut_error_struct

Dene DUT error response

Category
Predened struct

Syntax
struct dut_error_struct { message: string; source_struct(): any_struct; source_location(): string;
9-4 Preliminary

e Language Reference Manual

dut_error_struct

Checks and Error Handling

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(); }; }; };

Struct Members
message source_struct() source_location() source_struct_name() The message that was dened by the temporal or data DUT check and is printed by dut_error_struct.write(). Returns a reference to the struct where the temporal or data DUT check is dened. Returns a string giving the line number and source module name, for example, At line 13 in @checker. 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.

e Language Reference Manual

Preliminary

9-5

Checks and Error Handling

dut_error_struct

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. The rst method that is called when a DUT error occurs. This method is dened 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. 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. You can extend this method to perform additional actions.

pre_error()

write()

Description
The predened struct dut_error_struct denes the DUT error response. To modify the error response, extend either write() or pre_error().

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 { 9-6 Preliminary

e Language Reference Manual

dut_error_struct

Checks and Error Handling


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(); }; }; }; 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(); }; }; '>

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;

e Language Reference Manual

Preliminary

9-7

Checks and Error Handling

set_check()

}; 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); }; }; }; '>

Example 3
This example shows how error messages can be handled within units. (See Units Overview on page 5-1 for a description of units and modular verication.) 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(); }; }; }; '>

9.1.4
Purpose

set_check()

Set check severity

9-8

Preliminary

e Language Reference Manual

set_check()

Checks and Error Handling

Category
Predened routine

Syntax
set_check(static-match, check-effect) Syntax example:
<' extend sys { setup() is also { set_check("...", WARNING); }; }; '>

Parameters
static-match Only checks whose message string matches this regular expression are modied. The match string must use AWK-like syntax. See String Matching on page 2-54 in the e Language Reference. Note You must enclose AWK-like syntax in forward slashes, for example /Vio/. check-effect One of the following: error, error_break_run, error_automatic, error_continue, warning, ignore.

Description
Sets the severity or the check effect of specic DUT checks, so that failing checks will produce errors or warnings.

Example
Loading the following extension changes the check effect of all currently dened checks to WARNING.
<' extend sys { setup() is also { set_check("...", WARNING); };

e Language Reference Manual

Preliminary

9-9

Checks and Error Handling


}; '>

Handling User Errors

9.2

Handling User Errors

The e language has several constructs that help you handle user errors, such as le I/O errors or semantic errors. This section describes the constructs used for handling these kinds of errors:

warning() on page 9-10, which issues a warning message when a given error occurs. error() on page 9-11, which issues an error message and exits to the prompt when a
given error is detected.

fatal() on page 9-13, which issues an error message and exits to the UNIX prompt when
a given error is detected.

try on page 9-14, which denes an alternative response for xing or bypassing an error.

9.2.1
Purpose

warning()

Issue a warning message

Category
Action

Syntax
warning(warning-exp, ) Syntax example:
warning("len exceeds 50");

Parameter
warning-exp String or an expression that can be converted to a string. When the warning action is executed, the warning-exps are converted to strings, concatenated, and printed to the screen.
Preliminary

9-10

e Language Reference Manual

error()

Checks and Error Handling

Description
Issues the specied 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); }; };

See Also
error() on page 9-11 fatal() on page 9-13 try on page 9-14

9.2.2
Purpose

error()

Issue an error message.

Category
Action

Syntax
error(error-exp, ) Syntax example:
check_size() is { if (pkt.size != LARGE) { error("packet size is ", pkt.size); }; };

e Language Reference Manual

Preliminary

9-11

Checks and Error Handling

error()

Parameter
error-exp String or an expression that can be converted to a string. When the error action is executed, the error-exps are converted to strings, concatenated, and printed to the screen.

Description
Issues the specied error message, halts all methods being currently run, and returns to the prompt. The only exception to this is if the error action appears inside the rst action block given in a try action. In that case, execution continues from the else action block within the try action.

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); }; }; }; '>

See Also
warning() on page 9-10 fatal() on page 9-13 try on page 9-14

9-12

Preliminary

e Language Reference Manual

fatal()

Checks and Error Handling

9.2.3
Purpose

fatal()

Issue error message and exit to the UNIX prompt.

Category
Action

Syntax
fatal(fatal-error-exp, ) Syntax example:
fatal("Run-time error - exiting");

Parameter
fatal-error-exp String or an expression that can be converted to a string. When the fatal() action is executed, the fatal-error-exps are converted to strings, concatenated, and printed to the screen.

Description
Issues the specied error message, halts all activity, and returns to the UNIX prompt. fatal() returns a non-zero status to the UNIX shell.

See Also
warning() on page 9-10 error() on page 9-11 try on page 9-14

e Language Reference Manual

Preliminary

9-13

Checks and Error Handling

try

9.2.4
Purpose

try

Dene an alternative response for xing 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 rst action block (following try) cannot include the fatal() action. Subsequent action blocks (following else) can.

Description
Executes the action block following try. If an error occurs, executes the action block specied in the else clause, in which the error can be xed or handled. If no error occurs, the else clause is skipped. If you do not specify an else clause, execution after errors continues normally from the rst action following the try block.

9-14

Preliminary

e Language Reference Manual

try

Checks and Error Handling

Example
The following code example shows the use of warning(), error(), fatal(), and try. The code is intended to open a log le. If the log le cannot be opened, the simulation issues a warning and tries to open a temporary log le. If the temporary log le 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 9-10 error() on page 9-11 fatal() on page 9-13

e Language Reference Manual

Preliminary

9-15

Checks and Error Handling

Handling Programming Errors

9.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.

9.3.1
Purpose

assert

Check the e code for correct behavior

Category
Action

Syntax
assert bool-exp [else error(error-exp, )] Syntax example:
assert a < 20;

Parameters
bool-exp error-exp Boolean expression that checks the behavior of the code. String or an expression that can be converted to a string. If the bool-exp is FALSE, the error-exps are converted to strings, concatenated, and printed to the screen (and to the log le 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 specied error message plus the line number for and name of the le 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.

9-16

Preliminary

e Language Reference Manual

assert

Checks and Error Handling

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"); }; }; '>

See Also
warning() on page 9-10 error() on page 9-11 fatal() on page 9-13 try on page 9-14

e Language Reference Manual

Preliminary

9-17

Checks and Error Handling

assert

9-18

Preliminary

e Language Reference Manual

10

Constraints

Constraints are directives that are declared within a struct and dene the legal values of data items within the struct and its subtree. There are two basic types of constraints:

Hard constraints must be met or an error is issued. Soft constraints suggest default values but can be overridden by hard constraints.
You can dene constraints in many ways:

By dening a range of legal values in the eld or variable declaration By dening a list size in the list declaration By using one of the keep construct variations within a struct denition
This chapter contains the following sections:

Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

10.1 Basic Concepts of Constraints


The following sections introduce basic concepts related to constraints.

Order of Evaluation of Soft Constraints on page 10-2 Constraining Lists on page 10-2
e Language Reference Manual
Preliminary 10-1

Constraints

Order of Evaluation of Soft Constraints

Constraining Bit Slices on page 10-4

10.1.1

Order of Evaluation of Soft Constraints

Soft constraints are evaluated in reverse order of denition. If a soft constraint conicts with the constraints that have already been applied, it is skipped.

Example
keep keep keep keep x in soft soft soft [1..10]; x > 3; x==8; x < 6;

The evaluation of the constraints is as follows: 1. The hard constraint is applied, so the range is [1..10]. 2. The last soft constraint in the code order, x < 6, is considered. It does not conict with the current range, so it is applied. The range is now [1..5]. 3. The next to last soft constraint, x == 8, conicts with the current range, so it is skipped. The range is still [1..5]. 4. The rst soft constraint in the code order, x > 3, does not conict with the current range, so it is applied. The nal range of legal values is [4, 5].

See Also
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

10.1.2

Constraining Lists

There are several ways that you can constrain a list or its elements. See the following sections for more information:

List Size on page 10-3 List Item on page 10-3 Multiple List Items on page 10-3 List of Structs on page 10-3
10-2 Preliminary

e Language Reference Manual

Constraining Lists

Constraints

Multiple Lists on page 10-3

10.1.2.1 List Size


You can constrain the list size of a eld either by using a size expression in a eld declaration or by using a keep constraint. The following statements both constrain the number of elements in the pacs list to 10:
pacs[10]: list of pac; keep pacs.size() == 10;

If you unpack data into a eld declared as a list, it is better to use the size expression in a eld declaration. That way, the lists size is always exactly as specied. See Packing and Unpacking Lists on page 16-10 for more information. To constrain the list size of a variable, you must use the keep constraint. A size expression in a variable declaration is not allowed.

10.1.2.2 List Item


You can constrain an individual item in a list using the keep constraint.
keep me.data[0] == 0x9a;

10.1.2.3 Multiple List Items


You can constrain multiple items in a list, using the keep for each constraint.
keep for each in pacs { index == 0 => it.kind == control; };

10.1.2.4 List of Structs


You can constrain a list of structs to have all legal values of one or more elds, using the .is_all_iterations() method.
keep pacs.is_all_iterations(.kind);

10.1.2.5 Multiple Lists


You can constrain a list to be a subset of another list, using the in construct. In this example, all the elements in the pacs_sub list are contained in the pacs list, but not necessarily in the same order. The pacs list can have elements that are not in pacs_sub.

e Language Reference Manual

Preliminary

10-3

Constraints
pacs_sub[10]: list of pac; keep pacs_sub in pacs;

Constraining Bit Slices

You can constrain a list to have the same elements as another list using the is_a_permutation() pseudo-method. In this example, the pacs_dup list and the pacs list have exactly the same elements, but not necessarily in the same order.
pacs_dup[10]: list of pac; keep pacs_dup.is_a_permutation(pacs);

See Also
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

10.1.3

Constraining Bit Slices

You can use the bit slice operator in constraints to achieve a variety of purposes. A simple example is using the bit slice operator to constrain the elds of a CPU instruction:
struct cpu_env { instr: uint (bits: 16); keep instr[15:13] == 0b100; keep instr[12:8] == 0b11001; keep instr[7:0] == 0b00001111; };

Another simple but useful application of the bit slice constraint is to specify a list of even integers:
struct cpu_env { lint: list of int; keep for each in lint { it[0:0] == 0; }; };

You can also use a bit constraint to constrain particular bits in relation to each other. For example, the following constraint ensures that only one of the lower four bits of x is 1:
keep x[3:0] in [1,2,4,8];

You can use non-constant bit indices in bit slice constraints, as in the following example, to specify a 4-bit integer with 1s in two consecutive bits:
10-4 Preliminary

e Language Reference Manual

Constraining Bit Slices


i: int [0..3]; j: int [0..3]; l: int (bits: 4); keep j - i == 1; keep l[j:i] == 0b11;

Constraints

See Also
Bit Slice Constraints and Signed Entities on page 10-5 Bit Slice Constraints and Soft Constraints on page 10-6

10.1.3.1 Bit Slice Constraints and Signed Entities


Bit slices in e are treated as unsigned. It is possible, however, to constrain the value of a bit slice (or any unsigned entity) relative to a signed entity. In the example below, a bit slice of x is constrained by a signed entity, y:
x: int; y: int (bits:5); keep x[4:0] == y;

The value of the bit slice is treated as an unsigned integer; in other words, none of the
bits in the slice is treated as a sign bit. In the example above, although x can be a negative number, x[4:0] is treated as a positive value.

The value of the signed entity is generated as a non-negative. In the example above,
y will always be generated as a non-negative integer.

The value of both the bit slice and the signed entity must t into the smaller of The bit width of the bit slice The bit width of the highest possible value of the signed entity (This width excludes
one bit used to store the sign.) Example Given the following integers, x and y,
x: int; y: int (bits:5);

e Language Reference Manual

Preliminary

10-5

Constraints

Defining Constraints

any one of the following constraints requires the value of y to be a non-negative number no larger than four bits (the bit width of y, minus one bit to store the sign). In other words, the value of both y and the specied bit slice of x will be in the range [0..15]. Any upper bits of the bit slice not required to store the value are set to 0:
keep x[7:0] == y; keep x[4:0] == y; keep x[3:0] == y; // x[7:4] is 0 // x[4] is 0

By contrast, the value of y in the following constraint must t into only three bits (the bit width of the bit slice), so y and x[2:0] will be in the range [0..7]:
keep x[2:0] == y;

10.1.3.2 Bit Slice Constraints and Soft Constraints


A hard constraint on a bit slice of a variable always overrides a soft constraint on that variable. For example, the intention of the following constraints is to make all the bits of a scalar be zero by default, then set individual bits with bit slice constraints:
keep soft x == 0; keep x[7:7] == 1;

These constraints will not have the desired effect as the soft constraint will always be overridden. The only way to achieve this purpose is to apply the soft constraint to each individual bit explicitly:
keep soft x[0:0] == 0; ... keep soft x[31:31] == 0; keep x[7:7] == 1;

10.2 Defining Constraints


For information on the constructs used to dene constraints, see:

keep on page 10-7 keep struct-list.is_all_iterations() on page 10-9 keep for each on page 10-11 keep soft on page 10-13 keep soft select on page 10-15 keep item.reset_soft() on page 10-18
10-6 Preliminary

e Language Reference Manual

keep

Constraints

Constraining Lists on page 10-2 Constraining Bit Slices on page 10-4

10.2.1
Purpose

keep

Dene a hard constraint

Category
Struct member

Syntax
keep constraint-bool-exp Syntax example:
keep kind != tx or len == 16;

Parameters
constraint-bool-exp A simple or a compound Boolean expression. See constraint-bool-exp on page 10-20 for a full description of this parameter.

Description
States restrictions on the values of elds in the struct or the struct subtree, or describes required relationships between eld values and other items in the struct or its subtree.

Note
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 elds, kind and len. If the current pkt is of kind tx, then len must be 16.
e Language Reference Manual
Preliminary 10-7

Constraints
struct pkt { kind: [tx, rx]; len: int; keep kind == tx => len == 16; };

keep

Example 2
This example shows another way to describe the required relationship between the two elds, kind and len.
struct pkt { kind: [tx, rx]; len: int; when tx pkt { keep len == 16; }; };

Example 3
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 4
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; }; 10-8 Preliminary

e Language Reference Manual

keep struct-list.is_all_iterations()

Constraints

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
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

10.2.2
Purpose

keep struct-list.is_all_iterations()

Cause a list of structs to have all iterations of a eld

Category
Constraint-specic list method

Syntax
keep item.is_all_iterations(.eld_name, ) Syntax example:
keep packets.is_all_iterations(.kind,.protocol);

e Language Reference Manual

Preliminary

10-9

Constraints

keep struct-list.is_all_iterations()

Parameters
item eld_name An item of type list of struct. See constraint-item on page 10-23 for more information. A list of one or more scalar elds of a struct. The eld name must be prexed by a period. The order of elds in this list does not affect the order in which they are iterated. The specied eld that is dened rst in the struct is the one that is iterated rst.

Description
Causes a list of structs to have all legal, non-contradicting iterations of the elds specied in the eld list. Fields not included in the eld list are not iterated; their values can be constrained by other relevant constraints. The highest value always occupies the last element in the list. Soft constraints on elds specied in the eld list are skipped. All other relevant hard constraints on the list and on the struct are applied. If these constraints reduce the ranges of some of the elds in the eld list, then the resulting list is also reduced.

Notes
The list.is_all_iterations() method can only be used in a constraint Boolean expression. The elds to be iterated must be of a scalar type, not a list or struct type.

Example
The sys.packets list will have six elements (2 kinds * 3 protocols). The len eld is not iterated on; it will get any value from its legal range for each of the list items.
type p_kind: [tx, rx]; type p_protocol: [atm, eth, other]; struct packet { kind: p_kind; protocol: p_protocol; len: int [0..4k]; }; extend sys { packets: list of packet; keep packets.is_all_iterations(.kind,.protocol); }; 10-10 Preliminary

e Language Reference Manual

keep for each

Constraints

See Also
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

10.2.3
Purpose

keep for each

Constrain list items

Category
Struct member

Syntax
keep for each [(item-name)] [using [index (index-name)] [prev (prev-name)]] in item {constraint-bool-exp | nested-for-each; } Syntax example:
keep for each (p) in pkl { soft p.protocol in [atm, eth]; };

Parameters
item-name index-name prev-name An optional name referring to the current item in the list. The default is it. An optional name referring to index of the current item in the list. The default is index. An optional name referring to the previous item in the list. The default is prev.

e Language Reference Manual

Preliminary

10-11

Constraints

keep for each

item constraint-bool-exp

A constraint item of type list. See constraint-item on page 10-23 for more information. A simple or a compound Boolean expression. See constraint-bool-exp on page 10-20 for a full description of this parameter. A nested for each block, with the same syntax as the enclosing for each block, except that keep is omitted.

nested-for-each

Description
Denes a hard constraint on multiple list items.

Notes
You must refer to the constraint items using a path name that starts either with it, such
as it.pk or with the name that you assigned to the list item (item-name). Items whose pathname does not start with it can only be sampled; their values cannot be constrained.

Within a for each constraint, prev and index are predened constants and cannot be
constrained.

Referencing prev while in the rst item of the list is illegal. You can nest for each constraints.

Example 1
In this example, the keep for each in dat constraint in the pstr struct constrains all the dat elds to be less than 64. Note that referring to the list items in the Boolean expression it < 64 as dat[index] rather than it is illegal.
struct pstr { dat: list of uint; keep for each in dat { it < 64; }; };

Example 2
The following example uses an item name p and an index name pi to constrain the values of the variable indx:
10-12 Preliminary

e Language Reference Manual

keep soft
struct packet { indx: uint; }; extend sys { packets: list of packet; keep for each (p) using index (pi) in packets { p.indx == pi; }; };

Constraints

Example 3
The following example shows a nested for each block.
struct packet { protocol: p_protocol; %payload: list of byte; }; extend sys { packets: list of packet; keep for each (p) in packets { p.payload.size() == 6; for each in p.payload { it == index; }; }; };

See Also
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

10.2.4
Purpose

keep soft

Dene a soft constraint

Category
Struct member
e Language Reference Manual
Preliminary 10-13

Constraints

keep soft

Syntax
keep soft constraint-bool-exp Syntax example:
keep soft legal == TRUE;

Parameters
constraint-bool-exp A simple Boolean expression. See constraint-bool-exp on page 10-20 for a full description of this parameter.

Description
Suggests default values for elds or variables in the struct or the struct subtree, or describes suggested relationships between eld values and other items in the struct or its subtree. Soft constraints are order dependent and will not be met if they conict with hard constraints or soft constraints that have already been applied. See Order of Evaluation of Soft Constraints on page 10-2 for more information on this topic.

Note
The soft keyword can be used in simple Boolean expressions, but not in compound Boolean expressions. Thus the rst constraint below is legal, but the second is not:
keep x > 0 => soft y < 0; keep soft x > 0 => y < 0;

Example 1
In the following example, the default value of legal is TRUE.
struct instr { %opcode: cpu_opcode; legal: bool; keep soft legal == TRUE; keep legal => opcode in [ADD, SUB, AND, XOR, RET, NOP]; };

10-14

Preliminary

e Language Reference Manual

keep soft select

Constraints

Example 2
Individual constraints inside a constraint block can be soft constraints.
extend sys { packets: list of packet; keep for each in me.packets { soft .len == 2k; .kind != tx; }; };

See Also
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

10.2.5
Purpose

keep soft select

Constrain distribution of values

Category
Struct member

Syntax
keep soft item==select {weight: value; } Syntax example:
keep soft me.opcode == select { 30: ADD; 20: ADDI; 10: [SUB, SUBI]; };

e Language Reference Manual

Preliminary

10-15

Constraints

keep soft select

Parameters
item weight A constraint item. See constraint-item on page 10-23 for a full description of this parameter. Any uint expression. 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. A range list such as [2..7]. A select expression with a range list selects the portion of the current range that intersects with the specied range list. A constant expression. A select expression with a constant expression (usually a single number) selects that number, if it is part of the current range. Selects the portions of the current range that do not intersect with other select expressions in this constraint. Ignores this constraint and keeps the current range as is. Selects the values at the extreme ends of the current range(s).

value is one of the following: range-list

exp

others pass edges

Description
Species the relative probability that a particular value or set of values is chosen from the current range of legal values. The current range is the range of values as reduced by hard constraints and by soft constraints that have already been applied. Like other soft constraints, keep soft select is order dependent and will not be met if it conicts with hard constraints or soft constraints that have already been applied. See Order of Evaluation of Soft Constraints on page 10-2 for more information on this topic.

Example 1
The following soft select constraint species 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.
struct instr { %opcode: cpu_opcode; keep soft me.opcode == select { 30: ADD; 20: ADDI; 10: [SUB, SUBI]; 10-16 Preliminary

e Language Reference Manual

keep soft select


}; };

Constraints

Example 2
In the following example, address is constrained to the range [0..49] 10% of the time, as exactly [50] 60% of the time, and to the range [51..99] 30% of the time, assuming that the current range includes all these values.
struct transaction { address: uint; keep soft address == select { 10: [0..49]; 60: 50; 30: [51..99]; }; };

Example 3
This code uses the distribution described in the original denition of transaction only 10% of the time and uses the range [200..299] 90% of the time.
extend transaction { keep soft address == select { 10: pass; 90: [200..299]; }; };

The nal distribution is 90% [200..299], 1% [0..49], 6% [50], 3% [51..99].

Example 4
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.
extend transaction { keep address in [0..50,100..150]; keep soft address == select { 50: edges; 50: others; };

e Language Reference Manual

Preliminary

10-17

Constraints
};

keep item.reset_soft()

Example 5
This example shows how a run-time value from the simulation can be used to weight the selection of a value. In this case, the generation of the JMPC opcode is controlled by the value of the 'top.carry' signal.
extend instr { keep soft opcode == select { 40: [ADD, ADDI, SUB, SUBI]; 20: [AND, ANDI, XOR, XORI]; 10: [JMP, CALL, RET, NOP]; 'top.carry' * 90: JMPC; }; };

See Also
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

10.2.6
Purpose

keep item.reset_soft()

Quit evaluation of soft constraints for a eld

Category
Struct member

Syntax
keep item.reset_soft() Syntax example:
keep c.reset_soft();

10-18

Preliminary

e Language Reference Manual

keep item.reset_soft()

Constraints

Parameters
item A constraint item. See constraint-item on page 10-23 for a full description of this parameter.

Description
Terminates the evaluation of soft value constraints for the specied eld. Evaluation of soft constraints for other elds will continue.

Example 1
It is important to remember that soft constraints are considered in reverse order to the order in which they are dened in the e code. If the following constraints are dened in the order shown, the keep soft c > 5 and c < 10 constraint (the last one dened) is applied and then the evaluation of soft value constraints for c is terminated when the keep c.reset_soft() constraint is encountered. The keep soft c < 3 constraint is never considered. The keep soft d< 3 constraint is evaluated.
struct adder { c: uint; d: uint; keep soft c < 3; keep soft d < 3; }; extend adder { keep c.reset_soft(); }; extend adder { keep soft c > 5 and c < 10; };

See Also
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6

e Language Reference Manual

Preliminary

10-19

Constraints

constraint-bool-exp

10.2.7
Purpose

constraint-bool-exp

Dene a constraint on an item

Category
Expression

Syntax
bool-exp [or | and | => bool-exp] Syntax example:
z == x + y

Parameters
bool-exp An expression that returns either TRUE or FALSE when evaluated at run time.

Description
A constraint Boolean expression is a simple or compound Boolean expression that describes the legal values for at least one item or constrains the relation of one item with others. A compound Boolean expression is composed of two or more simple expressions joined with the or, and or implication (=>) operators. e has several special constructs that are useful in constraint Boolean expressions: soft A keyword that indicates that the constraint is a soft constraint. See Constraints on page 10-1 for a denition of these types of constraints. An expression that constrains the distribution of values. A pseudo-method that terminates the evaluation of soft constraints for a eld, in effect, removing previously dened soft constraints.

soft...select .reset_soft()

10-20

Preliminary

e Language Reference Manual

constraint-bool-exp

Constraints

.is_all_iterations()

A list method used only within constraint Boolean expressions that causes a list of structs to have all legal, non-contradicting iterations of the specied elds. A list method that can be used within constraint Boolean expressions to constrain a list to have the same elements as another list. An operator that can be used within constraints Boolean expressions to constrain an item to a range of values or a list to be a subset of another list. An operator that checks the subtype of a struct.

.is_a_permutation()

in

is [not] a

Notes
The soft keyword can be used in simple Boolean expressions, but not in compound
Boolean expressions. Thus the rst constraint below is legal, but the second is not:
keep x > 0 => soft y < 0; keep soft x > 0 => y < 0;

The order of precedence for Boolean operators is: and, or, =>. A compound expression
containing multiple Boolean operators of equal precedence is evaluated from left to right, unless parentheses are used to indicate expressions of higher precedence. See Example 3 on page 10-22.

Any e operator can be used in a constraint Boolean expression.

Example 1
The following are examples of simple constraint Boolean expressions:
long == TRUE soft x > y x == WIDTH x + z == y + 7 x in [0..10] (list_1) in (list_2) list_3.is_a_permutation(list_4) list_of_packets.is_all_iterations(.protocol) packet.reset_soft() packet is a legal packet soft me.opcode == select { 30: ADD; 20: ADDI; 10: [SUB, SUBI];

e Language Reference Manual

Preliminary

10-21

Constraints
};

constraint-bool-exp

Example 2
The following are examples of compound constraint Boolean expressions:
x > 0 and soft x < y is_a_good_match(x, y) => z < 1024 color != red or resolution in [900..999] packet is a good packet => length in [0..1023]

Example 3
In compound expressions where multiple implication operators are used, the order in which the operations are performed is signicant. For example, in the following constraint, the rst expression (a => b) is evaluated rst by default:
keep a => b => c; keep (not a or b) => c; keep a and (not b) or c; // is equivalent to // is equivalent to

However, adding parentheses around the expression (b => c) causes it to be evaluated rst, with very different results.
keep a => (b => c); keep a => (not b) or c; keep (not a ) or (not b) // is equivalent to // is equivalent to or c;

See Also
keep soft on page 10-13 keep item.reset_soft() on page 10-18 keep struct-list.is_all_iterations() on page 10-9 Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6 Scalar Types on page 3-2

10-22

Preliminary

e Language Reference Manual

constraint-item

Constraints

10.2.8
Purpose

constraint-item

Identies a constraint item

Category
Expression

Syntax
[me.]eld1-name[.eld2-name ] | it | [it].eld1-name[.eld2-name ] Syntax example:
me.protocol

Parameters
eld-name The name of a eld in the current struct or struct type.

Description
A constraint item is an operand in a Boolean expression that describes the legal values for that item or constrains its relation with another item. Every constraint must have at least one constraint item. In a keep for each constraint, the syntax for specifying a constraint item is a path starting with it, where it is the list item. In other keep constraints, the syntax for specifying a constraint item is a path starting with me of the struct containing the constraint and ending with a eld name.

See Also
Basic Concepts of Constraints on page 10-1 Dening Constraints on page 10-6 Implicit Variables on page 2-24

e Language Reference Manual

Preliminary

10-23

Constraints

constraint-item

10-24

Preliminary

e Language Reference Manual

11

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 within the simulation environment. This chapter contains the following sections:

Events Overview on page 11-1 Events and Expects on page 11-4 Sampling Events Overview on page 11-9 Predened Events Overview on page 11-11

Related Topics
Chapter 12, Temporal Expressions

11.1 Events Overview


An example of an event denition is shown in Figure 11-1 on page 11-2. An event named rclk is dened to be the rising edge of a signal named top.clk at another event named sim. The @ symbol is used with an event name, @event, to mean when the event is true. The special @sim syntax means at a callback from the simulator, or a spontaneous

e Language Reference Manual

Preliminary

11-1

Events

Events Overview

event in a formal verication setting. The rise() expression always causes a callback when the signal rises. Therefore, this event denition means a rise of top.clk causes rclk to occur. Occurrences of the rclk event are represented by arrows. Figure 11-1 Event Denition Example

event rclk is rise(top.clk)@sim top.clk rclk time

Once an event has been dened, it can be used in as the sampling event in temporal constructs such as temporal expressions (see Chapter 12, Temporal Expressions) like the following:
expect {[1]; true(chk)@rclk};

The occurrence of any event is counted as a synchronous time step, or tick. Ticks are the nest grain clock that marks the passage of time. Some [redened events are provided as part of e. You can use event constructs within Verilog modules to dene your own events, called named events, like the rclk example above.

Related Topics
Events and Expects on page 11-4 Sampling Events Overview on page 11-9 Predened Events Overview on page 11-11

11-2

Preliminary

e Language Reference Manual

Causes of Events

Events

11.1.1

Causes of Events

The ways in which an event are made to occur are described below.

Syntax event a is (@b and @c)@d event a is rise('top.b')@sim event a is { @b; @c; @d }@e

Cause of the Event Derived from other events (see Chapter 12, Temporal Expressions). Derived from behavior of a simulated device (see Chapter 12, Temporal Expressions). A sequence of other events (see Chapter 12, Temporal Expressions)

Related Topic
Events Overview on page 11-1

11.1.2

Scope of Events

Events, Assumes, and Expects are proposed to become a part of a module denition in Verilog. Syntactically, event and expect are added to the list of module_item_declaration as dened in Table 12-2 of the Verilog Hardware Description Language (IEEE Std 1364-1995). Alternatively, Events, Assumes, and Expects are members of external objects associated with Verilog modules. Such external objects may reference each other as well as parts of the verication environment. All references to events are to event instances. The scoping rules are as follows:

If a path is provided, use the event dened in the module instance pointed to by the path. If no path is provided, the event is resolved at compile time. The enclosing module
instance is searched.

If the event instance is not found, a compile-time error is issued.

Related Topic
Events Overview on page 11-1

e Language Reference Manual

Preliminary

11-3

Events

Events and Expects

11.2 Events and Expects


This section describes the following constructs:

event on page 11-4 expect on page 11-6 assume on page 11-8

Related Topics
Events Overview on page 11-1 Sampling Events Overview on page 11-9 Predened Events Overview on page 11-11

11.2.1
Purpose

event

Dene a named event

Category
Module item declaration

Syntax
event event-type is temporal-expression Syntax example:
event clk is rise('top.cpu_clk') @sim;

11-4

Preliminary

e Language Reference Manual

event

Events

Parameters
event-type temporal-expression The name you give the event type. It can be any legal e identier. An event or combination of events and temporal operators. To use an event name alone as a temporal expression, you must prex the event name with the @ sign. For example, to dene 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 12, Temporal Expressions.

Description
Events are attached to temporal expressions, is temporal-expression syntax. An attached event is emitted automatically whenever the temporal expression attached to it succeeds.

Example 1
One way to cause a 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 2
In the following, top_clk and stop_ct are attached events of module m_str. The event stop_ct refers to the event start_ct through a global path.
module m_str; event top_clk is fall(top.r_clk) @sim; event stop_ct is {@top.start_ct; [1]} @top_clk; endmodule module top; event start_ct is rise(start_ct)@sim; m_str m1; endmodule

See Also
Chapter 12, Temporal Expressions
e Language Reference Manual
Preliminary 11-5

Events

expect

Events Overview on page 11-1 Sampling Events Overview on page 11-9 Predened Events Overview on page 11-11

11.2.2
Purpose

expect

Dene a temporal behavioral rule to be veried

Category
Module item declaration

Syntax
expect temporal-expression [else dut_error( string-exp )] Additional syntax: expect name is [only] temporal-expression [else dut_error( string-ex )] expect name Syntax example:
expect (@a => @b) @clk else dut_error("no b after a"); expect safty1 is eventually @c;

Parameters
name temporal-expression string-exp The name of the expect property. It can be any legal e identier. A temporal expression that is always expected to succeed. Typically involves a temporal yield (=>) operation. 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.

11-6

Preliminary

e Language Reference Manual

expect

Events

Description
An expect denes a property in e. If the temporal expression fails at its sampling event, an error is reported. The expect name can be used for control (for example, using it in a model checker directive prove name). The is only syntax is used to replace a previous denition of a property by the same name.

Example 1
module 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 @transmit_start => {[0..9];@transmit_end} @bus_clk else dut_error("Bus cycle did not end in 10 cycles"); endmodule

Example 2
In the following example, two expect statements are used to specify the following rules:

After the transmit_start event, from three to six bus_clk cycles may elapse
before the transmit_end event.

After the transmit_end event at least 6 cycles must elapse before the next
transmit_start event. Any violation of the rules above will cause an error.
module top; event clk is change(sysclk)@sim; event start_drive is rise(drive)@sim; event stop_drive is fall(drive)@sim; watcher watcher1; endmodule module watcher; expect drive_short is @top.start_drive => {[2..5];@top.stop_drive}@top.clk else dut_error("Rule 1: start-end time violation); expect drive_long is @top.start_drive => {[5] * fail @top.stop_drive}@top.clk else dut_error("Rule 2: end-start time violation); endmodule

e Language Reference Manual

Preliminary

11-7

Events

assume

See Also
Chapter 12, Temporal Expressions, in particular, => on page 12-27

11.2.3
Purpose

assume

Dene a temporal behavioral rule guaranteed by the environment

Category
Module item declaration

Syntax
assume temporal-expression [else dut_error( string-exp )] Additional syntax: assume name is [only] temporal-expression [else dut_error( string-exp )] assume name Syntax example:
assume (@a => @b) @clk else dut_error("no b after a"); expect safty1 is eventually @c; assume safty1;

Parameters
name temporal-expression string-exp The name of the assumed property. It can be any legal e identier. A temporal expression that is always expected to succeed. Typically involves a temporal yield (=>) operation. 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.

11-8

Preliminary

e Language Reference Manual

Sampling Events Overview

Events

Description
An assume denes a property of the environment that drives the design under test. For simulation purposes, assumes are treated exactly as expects. Formal verication tools and modular verication methodologies use assumes as environment properties. A named assume can be turned into an expect by using the expect name syntax. Expects can be turned into assumes similarly.

Example 1
In the following example, an assume statement is used to specify the following rule:

After the transmit_start event, the environment will not emit another
transmit_start before the transmit_end event.
module top; event clk is change(sysclk)@sim; event start_drive is rise(drive)@sim; event stop_drive is fall(drive)@sim; assume no_overlap is @start_drive => {[..]* fail @start_drive; @stop_drive}@clk; endmodule

11.3 Sampling Events Overview


Events are used to dene the points at which temporal expressions are sampled. An event attached to a temporal expression becomes the sampling event for the temporal expression. The event is attached using the @sampling-event syntax: temporal-expression @sampling-event The temporal expression is evaluated at every occurrence of the sampling event. The sampling period is the time from after one sampling event up to and including the next sampling event. All event occurrences within the same sampling period are considered simultaneous. Multiple occurrences of a particular event within one sampling period are considered to be one occurrence of that event. In Figure 11-2 on page 11-10, Q and R are previously dened events that occur at the points shown. The temporal expression Q@R means evaluate Q every time the sampling event R occurs. If Q has occurred since the previous R event, then Q@R succeeds upon the next occurrence of R. The nal Q@R success happens because the sampling period for the expression includes the last R event, which occurs at the same time as the last Q.

e Language Reference Manual

Preliminary

11-9

Events

Sampling Events Overview

Figure 11-2

Sampling Event for a Temporal Expression

cycle of Q Q cycle of R R Q@R time

If Q in the gure above is a temporal expression that includes other events, R is the default sampling event of the temporal expression. The default sampling event of a temporal expression applies to all subexpressions within the expression, except where it is overridden explicitly by another event embedded in the expression. The predened any event occurs every time any other event occurs in the test. Expressions that need the highest time resolution can be attached to the any event. The any event is the default sampling event for all temporal expressions. When an event has to be associated with a change in a Verilog variable, you can attach the name sim to the Verilog variable. The term @sim just represents a direct attachment to an event; no sim event ever actually occurs. In Figure 11-3 on page 11-10, S and T are previously dened events. Attaching @sim to each of these event names causes the event to occur when its conditions are true at the time of a callback. The any event occurs at every S event and every T event. The temporal expression S@T succeeds at every occurrence of T where S has occurred since the last T event. Figure 11-3 Occurrences of the any Event

S@sim T@sim any S@T time

11-10

Preliminary

e Language Reference Manual

Predefined Events Overview

Events

Related Topics
Events Overview on page 11-1 Events and Expects on page 11-4 Predened Events Overview on page 11-11

11.4 Predefined Events Overview


Predened events are emitted by the environment at particular points in time. They are described in the following section:

General Predened Events on page 11-11

Related Topics
Events Overview on page 11-1 Events and Expects on page 11-4 Sampling Events Overview on page 11-9

11.4.1

General Predened Events

Table 11-1 on page 11-11 lists the general predened events. Each environment may choose to provide additional predened events. The events are described in more detail after the table. Table 11-1 Predened Events Description Emitted on every tick. Emitted once at run start (time 0). Emitted when the run terminates. This event is emitted every time the simulators time has changed since the previous callback.

Predened Event any start_of_test quit new_time

e Language Reference Manual

Preliminary

11-11

Events

General Predefined Events

any
This is a special event that denes the highest granularity of time. The occurrence of any event in the system causes an occurrence of the any event at the same tick. For any temporal expression used without an explicit sampling event, any is used by default.

start_of_test
Emitted once at the start of a run. This event is typically used to anchor temporal expressions to the beginning of time. For example, in the following, the watchdog time is anchored to the beginning of the test by start_of_test:
module top; event clk is cycle @any; event watchdog is {@start_of_test; [100]}@clk; endmodule

quit
The event quit is emitted to denote the end of a run. It can be used to cause the evaluation of temporal expressions that contain the eventually temporal operator. This allows you to check for eventually temporal expressions that have not been satised.

new_time
The event new_time is emitted by the environment to denote the progression of simulation time. It is mostly used for visualization in the context of simulation.

Related Topics
Events Overview on page 11-1 Events and Expects on page 11-4 Sampling Events Overview on page 11-9

11-12

Preliminary

e Language Reference Manual

12

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. This chapter contains the following sections:

Temporal Expressions Overview on page 12-1 Temporal Operators and Constructs on page 12-11

Related Topics
Chapter 11, Events

12.1 Temporal Expressions Overview


Temporal expressions (TEs) are combinations of events and temporal operators that describe behavior in time. Temporal expressions can be used to dene the occurrence of events, or to time some activity directly. A TE states timing relationships between events and values of registers, variables, or other expressions. In a simulation world, this timing behavior is evaluated during one or more cycles during the test. A TE attached to an event is evaluated for every cycle in which the event occurs, as long as the struct in which the event is dened has not been terminated.

e Language Reference Manual

Preliminary

12-1

Temporal Expressions

Temporal Expressions Overview

Temporal expressions, used to dene model behavior as well as temporal properties, can be veried statically by a model checker for example. The same expressions can be checked dynamically during simulation. Temporal expressions are only legal in the following constructs:

event denitions expect struct members assume struct members


Every temporal expression has a sampling event, either stated specically for the TE or inherited from the context in which the TE exists. For example, the following event denition uses the TE rise('top.req')@clk, which means at every occurrence of clk, evaluate the HDL variable top.req to see if it has changed from low to high since the last clk:
event req is rise('top.req')@clk

The sampling event for this expression is clk. The @clk syntax means evaluate when clk occurs. The following sections provide more overview information about temporal expressions

Temporal Sequences on page 12-3 Success of a Temporal Expression on page 12-3 How Context Determines Evaluation Points on page 12-5 Using Verilog Objects in Temporal Expressions on page 12-6 Selected Applications of Temporal Expressions on page 12-7 Forms for Common Temporal Expressions on page 12-8

Related Topics
Temporal Operators and Constructs on page 12-11 Chapter 11, Events

12-2

Preliminary

e Language Reference Manual

Temporal Sequences

Temporal Expressions

12.1.1

Temporal Sequences

A temporal sequence is an expression written using the syntax {TE1;TE2}@s_event, where TE1 and TE2 are both temporal expressions and s_event is the sampling event for the entire sequence expression. The TE1 expression is evaluated at the rst occurrence of the event, and the TE2 expression is evaluated at the occurrence of the event subsequent to the success of TE1. Expressions used in sequences can be temporal expressions in any form. For example:
{@req; [1]; rise('top.ack')@clk}@pclk

The sequence above contains three temporal expressions:

@req - an event [1] - one cycle of the pclk sampling event rise('top.ack')@clk - a change of an HDL signal, evaluated at the clk event

Related Topic
Temporal Expressions Overview on page 12-1

12.1.2

Success of a Temporal Expression

Whenever the sampling event for a TE occurs, the TE is evaluated. At any sampling event, a TE is either true or false. The value of a TE can change between sampling events due to changes in variables or occurrences of other events between the TEs sampling events. After some number of evaluations, determined by the TEs contents, the TE either succeeds or fails:

If the TE is a sequence of subexpressions, it is evaluated as many times as there are


subexpressions in the sequence. For each evaluation, the temporal expression is true if the behavior it describes occurs at that time. If the temporal expression is true over the required number of evaluations, the expression succeeds. That is, when the temporal expression matches the actual behavior being checked, the TE succeeds.

If the expression is not true at any evaluation, it fails at that point.

e Language Reference Manual

Preliminary

12-3

Temporal Expressions

Success of a Temporal Expression

12.1.2.1 Notation in Temporals Graphics for Success or Failure


Figure 12-1 on page 12-4 shows the graphic notation used in illustrations in the e temporals documentation. Figure 12-1 Legend for Temporals Graphics

event emitted

evaluation starts

evaluation succeeds

evaluation fails

An example of the graphical notation to represent evaluation of temporal sequences is shown in Figure 12-2 on page 12-4. Figure 12-2 Evaluation of Three Sequences

pclk req ack {@req; @ack} @pclk {@req; [1]; @ack} @pclk {@req; @req} @pclk

Figure 12-2 on page 12-4 shows occurrences of three events, pclk, req, and ack. The pclk event is the sampling event for three sequences involving req and ack.

The {@req; @ack} sequence starts evaluating each time req occurs at pclk. When
ack occurs one pclk after req, the sequence succeeds.

The {@req; [1]; @ack} sequence likewise starts evaluating at the first req
occurrence at pclk, and shifts at the next pclk occurrence. When ack occurs at the third pclk, the sequence succeeds.
12-4 Preliminary

e Language Reference Manual

How Context Determines Evaluation Points

Temporal Expressions

The {@req; @req} sequence starts evaluating each time req occurs at pclk, and
fails when req does not occur again at the next pclk. Some sequences can succeed more than once during a particular evaluation. Figure 12-3 on page 12-5 shows an evaluation of a temporal expression that is the OR of two sequences. The rst sequence (a), {@req; @ack}@pclk, succeeds at the rst ack occurrence (second pclk occurrence). The second sequence (b), {@req; [1]; @ack}@plck, succeeds at the second ack occurrence (third pclk). When req occurs again at the fourth pclk occurrence, a new evaluation of the sequence starts. This evaluation succeeds upon the occurrence of ack at the fth pclk cycle. Evaluation of the (b) branch continues at the sixth pclk, where it fails and terminates. Figure 12-3 Evaluation of the OR of Two Sequences

pclk req ack (a) ({@req; @ack} or (b) {@req; [1]; @ack}) @pclk

(a)

(b)

(a)

(b)

Related Topic
Temporal Expressions Overview on page 12-1

12.1.3

How Context Determines Evaluation Points

The points at which a temporal expression is evaluated depend on its context. The point at which a temporal expression terminates also depends on whether it is a subexpression of a larger TE. The evaluation of TEs in modules (event and expect) is done according to the following:

A temporal expression attached to an event or specied in an assume or expect construct


starts evaluating when the simulation run starts. They are repeatedly evaluated on every sampling event until the run terminates.

e Language Reference Manual

Preliminary

12-5

Temporal Expressions

Using Verilog Objects in Temporal Expressions

Temporal expressions attached to events or specied in an assume or expect constructs


are always active in the context of model checking.

Related Topic
Temporal Expressions Overview on page 12-1

12.1.4

Using Verilog Objects in Temporal Expressions

To synchronize temporal expressions to Verilog simulator values, you dene an event to depend on a simulator variable (typically a clock), and then use the event as part of a temporal expression. To create an event dependent on a Verilog clock, register, or net, use the following syntax:
event event-name is (rise|fall|change)(verilog-variable) @sim

Using the @sim syntax creates a callback to the expression whenever the verilog-variable changes in the designated way. The event is emitted at that time. You can use HDL expressions in TEs sampled by any event, not just @sim. The HDL values are sampled at each occurrence of the given sampling event. In the following example, an event named clk is dened as the fall of a simulator signal named xor_top.clk.
module verify; event clk is fall(xor_top.clk)@sim; // Causes simulator callback event rdy is fall(xor_top.ready)@clk; // Does not cause callback endmodule

Verilog events can also be used to create temporal events. To utilize a Verilog event, use change(), as in the following example:
event ver_ev is change(xor_top.verilog_event1)@sim;

Related Topic
Temporal Expressions Overview on page 12-1

12-6

Preliminary

e Language Reference Manual

Selected Applications of Temporal Expressions

Temporal Expressions

12.1.5

Selected Applications of Temporal Expressions

This section describes the following:

Handling Overlapping Transactions on page 12-7 Restricting TE Matches on page 12-7

12.1.5.1 Handling Overlapping Transactions


Transactions can overlap in the sense that many of them can be active at the same time. These can be purely pipelined transactions or transactions that are identied by some key. Handling pipelined transactions is easy in e. For example, the following is a behavioral rule for a buffer with a latency of three cycles:
expect @buf.in => {[2]; @buf.out};

On many occasions, some data needs to be carried with the transaction. This might be the data on which some operation needs to be done or the key of a transaction. In such cases the solution is to maintain a transaction identier in Verilog that carries the data. That data can be used by the TE to identify the transaction components. The Verilog identier can be placed in an array, if multiple pipelined transactions need to be tracked.

12.1.5.2 Restricting TE Matches


A temporal expression in the context of an event or an expect is re-evaluated at every occurrence of the sampling event to see if there is any possible match of the behavior it describes. Sometimes a different behavior is expected, where not all matches are considered. For example, consider a component that handles xed length transactions. The basic behavior we want to check for is every transaction that starts will end after N cycles:
expect @trans.start => {[N]; @trans.end}@clk;

However, suppose that the design under test can only handle one transaction at a time. If a new transaction starts while the previous one is being processed, the component cannot handle the second transaction. The expect check fails because the component does not emit the expected transaction end. Since an expect automatically traces multiple transactions, you must explicitly rule out such cases.

e Language Reference Manual

Preliminary

12-7

Temporal Expressions

Forms for Common Temporal Expressions

To avoid matching unwanted starts, you need to explicitly dene the true conditions at which transactions are expected to end. For example, say the component protocol species that the component sends a busy signal as long as it is handling a transaction, and transaction starts are accepted only if the component is not busy. This can be implemented by the following alteration of the rule:
expect @trans.start and not @busy => {[N]; @trans.end}@clk;

Or if you want to explicitly state that start must not occur while a transaction is being processed, use the rule:
expect @trans.start => {[N]* not @trans.start;@trans.end}@clk;

Related Topic
Temporal Expressions Overview on page 12-1

12.1.6

Forms for Common Temporal Expressions

The natural way to specify future behavior is in terms of cause yields effect, which is done with the temporal yield operator (=>). The following is equivalent to the statement, A transaction start is followed within 1 to 4 cycles by a transaction end:
@transaction.start => {[..3]; @transaction.end};

The language also provides a way to maintain information about past events, which you can then use in yield operations like the above. This is done by dening a separate event for the past part, which starts a parallel thread separate from the main temporal expression thread. The following is equivalent to the statement, A transaction end is preceded by a transaction start within the previous 1 to 4 cycles:
event started is {@transaction.start; ~[2..5]}; @transaction.end => @started;

Temporal expressions for many situations are shown below. The desired conditions are stated, and then an expression is shown for those conditions. In these expressions, TEn is a temporal subexpression, which can be an event.

12.1.6.1 Examples of Sequence Expressions


TE1 and TE2 at the same time:
TE1 and TE2

TE1, then TE2 in the next cycle:


12-8 Preliminary

e Language Reference Manual

Forms for Common Temporal Expressions


{TE1; TE2}

Temporal Expressions

TE1 any number of times, then TE2:


{[..] * TE1; TE2}

TE2 in the nth cycle after TE1:


{TE1; [n - 1]; TE2}

TE2 within n cycles after TE1:


{TE1; [..n-1]; TE2}

TE2 within n1 to n2 cycles after TE1:


{TE1; [n1-1..n2-1]; TE2}

TE2 any number of cycles after TE1:


{TE1; [..]; TE2}

no TE2 before TE1:


{[..] * fail TE2; TE1 and fail TE2}

TE2 after n cycles of no TE1:


{[n] * fail TE1; TE2}

TE2 any number of cycles after TE1, with no TE3 in between:


{TE1; [..] * fail TE3; TE2}

TE2 one cycle after TE1, repeated n times:


([n] * {TE1; TE2})

TE1 after the last TE2 and before TE3:


{TE2; [..] * fail TE2; (TE1 and fail TE3 and fail TE2); [..] * fail TE2; TE3}

12.1.6.2 Examples of Behavioral Rule Checks


TE2 must occur one cycle after TE1:
expect TE1 => TE2 else dut_error("TE2 did not occur 1 cycle after TE1")

TE2 must occur within n1 to n2 cycles after TE1:


e Language Reference Manual
Preliminary 12-9

Temporal Expressions

Forms for Common Temporal Expressions

expect TE1 => {[n1-1..n2-1]; TE2} else dut_error("No TE2 ",n1," to ",n2," cycles after TE1")

If TE1 occurs then TE2 should eventually occur:


expect TE1 => (eventually TE2) else dut_error("TE1 occurred but not TE2")

If TE1, then TE2 must not occur for n cycles:


expect TE1 => [n] * fail TE2 else dut_error("TE2 less than ",n," cycles after TE1")

If TE2, then TE1 must have occurred n cycles earlier:


event te1_occ is {TE1; [n + 1]}; expect TE2 => @te1_occ; else dut_error("TE2 without TE1 ",n," cycles earlier")

If TE2, then TE1 must have occurred sometime before:


event te1_occ is {TE1; ~[2..]}; expect TE2 => @te1_occ; else dut_error("TE2 without a previous TE1")

There must be no more than n occurrences of TE3 after TE1 and before TE2:
expect {TE1; [n] * {[..]; TE3}} => {[..] * fail TE3; TE2} else dut_error("TE3 too many times between TE1 and TE2")

TE must not occur more than n times during the test:


expect @start_of_test => fail{[n + 1] * {[..]; TE}} else dut_error("TE occurred more than ",n," times")

Related Topic
Temporal Expressions Overview on page 12-1

12-10

Preliminary

e Language Reference Manual

Temporal Operators and Constructs

Temporal Expressions

12.2 Temporal Operators and Constructs


This section describes the constructs you can use in temporal expressions:

fail on page 12-12 and on page 12-14 or on page 12-15 { exp ; exp } on page 12-17 eventually on page 12-19 [num] on page 12-20 [ exp..exp ] on page 12-22 ~[ exp..exp ] on page 12-24 => on page 12-27

@unary event operator on


page 12-28

@ binary sampling operator on


page 12-29

cycle on page 12-31 true(exp) on page 12-32 change(exp), fall(exp), rise(exp) on


page 12-33

exec on page 12-36

Related Topic
Temporal Expressions Overview on page 12-1

12.2.1

Precedence of Temporal Operators

The precedence of temporal operators is shown in Table 12-1, listed from highest precedence to lowest. Table 12-1 Precedence of Temporal Operators Operator Example @event-name TE exec action-block [ ] * TE fail TE TE1 and TE2 TE1 or TE2
Preliminary 12-11

Operator Name named event exec repeat fail and or


e Language Reference Manual

Temporal Expressions

fail

Table 12-1

Precedence of Temporal Operators (continued) Operator Example {TE1 ; TE2} TE1 => TE2 TE @ event-name

Operator Name sequence yield sample event

Related Topic
Temporal Expressions Overview on page 12-1

12.2.2
Purpose

fail

Temporal expression failure operator

Category
Temporal expression

Syntax
fail temporal-expression Syntax example:
fail{@ev_a; @ev_b};

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)), then the expression succeeds if and when all the interpretations fail.

12-12

Preliminary

e Language Reference Manual

fail

Temporal Expressions

The expression fail TE succeeds at the point where all possibilities to satisfy TE have been exhausted. Any expression TE can fail at most once per sampling event occurrence. The failing sequence is always the minimal sequence that can cause a failure. Figure 12-4 Comparison of Temporal not and fail Operators
ev_a, ev_b

ev_a ev_a, ev_b, ev_c events @smpl sampling event {@ev_b;@ev_c}@smpl

ev_b ev_c

fail{@ev_b;@ev_c}@smpl {@ev_a; fail{@ev_b;@ev_c}@smpl}

event emitted

evaluation starts

evaluation succeeds

evaluation fails

Example
The expression below succeeds for any of the following conditions:

Event ev_a does not occur in the rst cycle. ev_a succeeds in the rst cycle, but then event ev_b does not occur in the
second cycle.

ev_a succeeds in the rst cycle and ev_b succeeds in the second cycle, but then
event ev_c does not occur in the third cycle.
fail{@ev_a; @ev_b; ev_c}@smpl;

e Language Reference Manual

Preliminary

12-13

Temporal Expressions

and

See Also
Temporal Operators and Constructs on page 12-11

12.2.3
Purpose

and

Temporal expression logical 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 succeed.

Example
Evaluation of the temporal and operation:
event TE3 is (TE1 and TE2)@Q

Is shown in Figure 12-5 on page 12-15, for the following conditions:

Evaluation of TE1 and TE2 begins on the rst Q. Both TE1 and TE2
evaluate to TRUE between the second and third Q, so TE3 evaluates to TRUE at the third Q.

12-14

Preliminary

e Language Reference Manual

or

Temporal Expressions

The evaluations of TE1 and TE2 that begin on the fourth Q eventually result
in success of TE1 and TE2, but TE1 succeeds before the fth Q, and TE2 succeeds before the sixth Q. Therefore, TE3 does not succeed.

On the seventh Q, evaluation of TE1 begins, and it succeeds before the eighth
Q. However, the corresponding evaluation of TE2 fails during that period, so TE3 fails. Figure 12-5 Example of Temporal and Operator Behavior

1 Q TE1 TE2 (TE1 and TE2) @Q TE3

10

event emitted

evaluation starts

evaluation succeeds

evaluation fails

See Also
Sampling Events Overview on page 11-9 Temporal Operators and Constructs on page 12-11

12.2.4
Purpose

or

Temporal expression logical or operator

e Language Reference Manual

Preliminary

12-15

Temporal Expressions

or

Category
Temporal expression

Syntax
temporal-expression or temporal-expression Syntax example:
(TE1 or TE2)@clk

Parameters
temporal-expression A temporal expression.

Description
The temporal or operation succeeds when either temporal expression succeeds. An or operation creates a fork, with a separate thread for each of its temporal expressions. It can create multiple matches (successes) for a single temporal expression evaluation. If both of its temporal expressions succeed, a single or operation can succeed twice, during different sampling event cycles. As such, the temporal or is the source of non-determinism.

Note
First match repeat and true match repeat operations (see variable repeat operator { exp ; exp } on page 12-17) are shorthand for multiple OR operations. They derive their ability to succeed multiple times from the temporal or operator.

Example
Evaluation of the temporal or operation:
event TE3 is (TE1 or TE2) @Q;

is shown in Figure 12-6 on page 12-17, for the following conditions:

Evaluation of TE1 and TE2 begins on the rst Q. Both TE1 and TE2
evaluate to TRUE between the second and third Q, so TE3 evaluates to TRUE at the third Q.

12-16

Preliminary

e Language Reference Manual

{ exp ; exp }

Temporal Expressions

The evaluations of TE1 and TE2 that begin on the fourth Q eventually result
in success of TE1 and TE2, so TE3 succeeds.

On the seventh Q, evaluation of TE1 begins, and it succeeds before the ninth
Q, so TE3 succeeds. Figure 12-6 Example of Temporal or Operator Behavior

1 Q TE1 TE2 (TE1 or TE2) @Q TE3

10

event emitted

evaluation starts

evaluation succeeds

evaluation fails

See Also
Sampling Events Overview on page 11-9 Temporal Operators and Constructs on page 12-11

12.2.5
Purpose

{ exp ; exp }

Temporal expression sequence operator

Category
Temporal expression

e Language Reference Manual

Preliminary

12-17

Temporal Expressions

{ exp ; exp }

Syntax
{temporal-expression; temporal-expression; } Syntax example:
{@ev_d; @ev_e} @ev_f

Parameters
temporal-expression A temporal expression.

Description
The semicolon (;) sequence operation evaluates a series of temporal expressions over consecutive occurrences of a specied sampling event. Each temporal expression following a ; starts evaluating in the sampling period following the period in which the preceding temporal expression succeeded. The sequence succeeds in the sampling event period in which its nal expression succeeds.

Note
Curly braces ({}) in the scope of a temporal expression dene a sequence. They should not be used in any other way.

Example
Figure 12-7 on page 12-19 shows the results of evaluating the temporal sequence:
{@ev_a; @ev_b; @ev_c} @Q;

over the series of ev_a, ev_b, and ev_c events shown at the top of the gure. Evaluation of the sequence starts whenever event ev_a occurs.

12-18

Preliminary

e Language Reference Manual

eventually

Temporal Expressions

Figure 12-7

Example Evaluations of a Temporal Sequence

1 Q ev_a ev_b ev_c {@ev_a;@ev_b;@ev_c}@Q

event emitted

evaluation starts

evaluation succeeds

evaluation fails

See Also
Sampling Events Overview on page 11-9 Temporal Operators and Constructs on page 12-11

12.2.6
Purpose

eventually

Temporal expression success check

Category
Temporal expression

Syntax
eventually temporal-expression Syntax example:
{@ev_d; eventually @ev_e}

e Language Reference Manual

Preliminary

12-19

Temporal Expressions

[num]

Parameters
temporal-expression A temporal expression.

Description
Species that a temporal expression is expected to succeed sometime in the future. The end of time during simulation is denoted by the quit event. All eventually expressions are expected to succeed before that event.

Example
The following temporal yield operation (see => on page 12-27) succeeds only if, after event ev_c occurs, event ev_a occurs in the next cycle, and then event ev_b occurs sometime before the ex_str struct instance is terminated. (The {...;...} syntax species a temporal sequence. The expressions are evaluated one after the other, in consecutive sampling periods. See { exp ; exp } on page 12-17 for information about the ; sequence operator).
struct ex_str { event ev_a; event ev_b; event ev_c; expect @ev_c => {@ev_a; (eventually @ev_b)}; };

See Also
quit on page 11-12 Temporal Operators and Constructs on page 12-11

12.2.7
Purpose

[num]

Fixed repetition operator

Category
Temporal expression

12-20

Preliminary

e Language Reference Manual

[num]

Temporal Expressions

Syntax
[exp] [* temporal-expression] Syntax example:
wait [2]*cycle;

Parameters
exp A 32-bit, non-negative integer expression, which species the number of times to repeat the evaluation of the temporal expression. A constant expression is required for model checking applications. A temporal expression that is to be evaluated the number of times specied by numeric-expression. When you want to wait or delay for a certain number of sampling points, you can use the cycle temporal expression with the repeat operator. If you do not specify * temporal-expression, * cycle is automatically used in its place.

temporal-expression

Description
Repetition of a temporal expression is frequently used to describe cyclic or periodic temporal behavior. The [num] xed repeat operation species a xed 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 species a temporal sequence. The expressions are evaluated one after another, in consecutive sampling periods. See { exp ; exp } on page 12-17 for information about the ; sequence operator. In the following example, the event ev_s succeeds after the sequence event ev_a, then three occurrences of event ev_b, then event ev_c, all sampled by the ev_clk event:
event ev_s is {@ev_a; [3]*@ev_b; @ev_c}@ev_clk;

e Language Reference Manual

Preliminary

12-21

Temporal Expressions

[ exp..exp ]

See Also
Temporal Operators and Constructs on page 12-11

12.2.8
Purpose

[ exp..exp ]

First match variable repeat operator

Category
Expression

Syntax
[[from-exp]..[to-exp] ] [* temporal-expression_1]; temporal-expression_2 Syntax example:
[2..4]*@pclk;@reset

Parameters
from-exp An expression that evaluates to a non-negative number of 32 bits or fewer. This species the minimum number of repetitions of the temporal expression. If the from-exp is missing, zero is used.

12-22

Preliminary

e Language Reference Manual

[ exp..exp ]

Temporal Expressions

to-exp

An expression that evaluates to a non-negative number of 32 bits or fewer, which must be greater than or equal to the from-exp. This species the maximum number of repetitions of the temporal expression. If the to-exp is missing, innity (MAX_INT for simulation) is used. The temporal expression that is to be sampled some number of times within the from-exp..to-exp range. When you want to wait or delay for a certain number of sampling points, you can use the cycle temporal expression with the repeat operator. If you do not specify * temporal-expression, * cycle is automatically used in its place. The temporal expression that is sampled after each success of temporal-expression1. Success of temporal-expression2 after a specied number of temporal-expression1 successes results in success of the entire rst match repeat expression.

temporal-expression1

temporal-expression2

Description
You can use a [..] variable repeat operation to specify a range of possible numbers of occurrences of a temporal expression. Repeat also enables specication of behavior over innite sequences by repeating an innite number of occurrences of a temporal expression. First match variable repeat matches on the rst occurrence of a temporal expression after a number of repetitions within the specied range.

e Language Reference Manual

Preliminary

12-23

Temporal Expressions

~[ exp..exp ]

If ev_a is an event occurrence, [..]*TE1;@ev_a is equivalent to: {@ev_a} or {[1]*(fail @ev_a) and TE1; @ev_a} or {[2]*(fail @ev_a) and TE1; @ev_a}

Examples
The {...;...} syntax used in the examples below species a temporal sequence. The expressions are evaluated one after the other, in consecutive sampling periods. See { exp ; exp } on page 12-17 for information about the ; sequence operator. In the following example, event ev_1 is emitted with the rst occurrence of ev_clk that coincides or follows ev_2:
event ev_1 is {[..]; @ev_2}@ev_clk;

In the following example, the event ev_3 is emitted after one or more occurrences of ev_1, followed by one occurrence of ev_2:
event ev_3 is {[1..]*@ev_1; @ev_2}@ev_clk;

In the following example, the event ev_4 is emitted after zero to three occurrences of the sequence ev_1; ev_2, followed by one occurrence of ev_3:
event ev_4 is {[..3]*{@ev_1; @ev_2};@ev_3}@ev_clk;

See Also
~[ exp..exp ] on page 12-24 cycle on page 12-31 [num] on page 12-20 Temporal Operators and Constructs on page 12-11

12.2.9
Purpose

~[ exp..exp ]

True match variable repeat operator

Category
Expression
12-24 Preliminary

e Language Reference Manual

~[ exp..exp ]

Temporal Expressions

Syntax
~[[from-exp]..[to-exp]] [* temporal-expression] Syntax example:
~[2..4]*@pclk

Parameters
from-exp An expression that evaluates to a non-negative number of 32 bits or fewer. This species the minimum number of repetitions of the temporal expression. If the from-exp is missing, zero is used. An expression that evaluates to a non-negative number of 32 bits or fewer, which must be greater than or equal to the from-exp. This species the maximum number of repetitions of the temporal expression. If the to-exp is missing, innity (MAX_INT for simulation) is used. The temporal expression that is to be sampled some number of times within the from-expr..to-exp range. When you want to wait or delay for a certain number of sampling points, you can use the cycle temporal expression with the repeat operator. If you do not specify * temporal-expression, * cycle is automatically used in its place.

to-exp

temporal-expression

Description
You can use a ~[..] variable repeat operation to specify a range of possible numbers of occurrences of a temporal expression. Repeat also enables specication of behavior over innite sequences by repeating an innite number of occurrences of a temporal expression. True match variable repeat matches all occurrences of the expression. This expression creates threads of evaluations after every number of repetitions within the range. The expression ~[..]*TE is equivalent to: [0] or [1]*TE or [2]*TE The true match variable repeat succeeds after any number of repetitions of the temporal expression within the designated range. This construct is useful for maintaining information about past events.The following are examples of both forms of variable repeats, using implicit and explicit from - to range expressions:
e Language Reference Manual
Preliminary 12-25

Temporal Expressions

~[ exp..exp ]

Example 1
In the examples below, the {...;...} syntax species a temporal sequence. The expressions are evaluated one after the other, in consecutive sampling periods. See { exp ; exp } on page 12-17 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; B, or A; B; B, or A; B; B; B:


{@A;~[1..3]*@B}

Example 2
The following temporal expression succeeds three pclk cycles after reset occurs, again at four pclk cycles after reset, and again ve pclk cycles after reset (with reset also sampled at pclk):
{@reset; ~[3..5]} @pclk

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 efcient way to write the above example is:


(@A and @B) or {@A; [..]; @B}

See Also
[ exp..exp ] on page 12-22 cycle on page 12-31 [num] on page 12-20 Temporal Operators and Constructs on page 12-11
12-26 Preliminary

e Language Reference Manual

=>

Temporal Expressions

12.2.10 =>
Purpose
Temporal yield operator

Category
Temporal expression

Syntax
temporal-expression1 => temporal-expression2 Syntax example:
@A => {[1..2]*@clk; @B};

Parameters
temporal-expression1 temporal-expression2 The rst temporal expression. The second temporal expression is expected to succeed if this expression succeeds. The second temporal expression. If the rst temporal expression succeeds, this expression is also expected to succeed.

Description
The yield operator is used to assert that success of one temporal expression must be followed by success of another temporal expression. The temporal yield operator behaves differently from the Boolean logic implication operator TE1 => TE1 (not TE1 or TE2). The yield operator TE1 => TE2 is equivalent to (fail TE1) or {TE1 ; TE2}. The operator creates a sequence of two expressions. The yield expression succeeds if the rst expression fails. If the rst expression succeeds, then the second expression must succeed sometime later. Yield is typically used in conjunction with the expect struct member to express temporal rules.

e Language Reference Manual

Preliminary

12-27

Temporal Expressions

@unary event operator

Example
The following temporal expression succeeds if acknowledge occurs 1 to 100 cycles after request occurs. (The {...;...} syntax species a temporal sequence. The expressions are evaluated one after the other, in consecutive sampling periods. See { exp ; exp } on page 12-17 for information about the ; sequence operator).
expect @request => {[..99]; @acknowledge};

See Also
expect on page 11-6 Temporal Operators and Constructs on page 12-11

12.2.11 @unary event operator


Purpose
Use an event as a temporal expression

Category
Temporal expression

Syntax
@event-type Syntax example:
event ev_rst is @rst;

Parameters
event-type The name of an event. This can be either a predened event or a user-dened event.

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.
12-28 Preliminary

e Language Reference Manual

@ binary sampling operator

Temporal Expressions

Examples
In the following, pclock is a temporal expression:
@pclock

The predened any event occurs at every tick. As a sampling event, use it as follows:
@any

See Also
event on page 11-4 Predened Events Overview on page 11-11 Temporal Operators and Constructs on page 12-11

12.2.12 @ binary sampling operator


Purpose
Specify a sampling event for a temporal expression

Category
Temporal expression

Syntax
temporal-expression @event-type Syntax example:
wait cycle @reset;

Parameters
temporal-expression event-type A temporal expression, which will be sampled at the specied sampling-event. The name of an event dened using the event struct member, or the name of a predened event. It cannot be a temporal expression.
Preliminary 12-29

e Language Reference Manual

Temporal Expressions

@ binary sampling operator

Description
Used to specify the sampling event for a temporal expression. The specied 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 of the parent expression by attaching a different sampling event to the subexpression. 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 specied with the @ binary event operator. 2. For a subexpression, the sampling event inherited from its parent expression. 3. If none of the above applies, the predened any event.

Note
The special sampling event @sim can be used only with change, fall, and rise operations on HDL objects and Verilog events. This will cause a callback whenever a change, fall or rise happen, respectively, during simulation.

Examples
The reset event is sampled at the pclk event:
@reset @pclk

The reset event is sampled at the predened any event:


@reset @any

Event e_a occurs when the reset event occurs, sampled at the rclk event:
event e_a is @reset @rclk;

The following is the same as event e_b is @reset @any:


event e_b is @reset;

See Also
event on page 11-4 Predened Events Overview on page 11-11
12-30 Preliminary

e Language Reference Manual

cycle

Temporal Expressions

Sampling Events Overview on page 11-9 Temporal Operators and Constructs on page 12-11

12.2.13 cycle
Purpose
Specify an occurrence of a sampling event

Category
Temporal expression

Syntax
cycle Syntax example:
event ev_c is cycle @ev_clk;

Description
Represents one cycle of an event. With no explicit sampling event specied, this represents one cycle of the default sampling event. With a sampling event specied, cycle is equivalent to @sampling-event @any. You can use the cycle expression to override the default sampling event taken from the context.

Example 1
The following expression succeeds one ev_clk after ev_d:
event ev_d1 is { @ev_d; cycle}@ev_clk;

See Also
event on page 11-4 Predened Events Overview on page 11-11 Sampling Events Overview on page 11-9
e Language Reference Manual
Preliminary 12-31

Temporal Expressions

true(exp)

@ binary sampling operator on page 12-29 Temporal Operators and Constructs on page 12-11

12.2.14 true(exp)
Purpose
Boolean temporal expression

Category
Temporal expression

Syntax
true(bool-exp) Syntax example:
event rst is true(reset == 1) @clk;

Parameters
bool-exp 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 true(exp) @samp does not succeed if exp becomes true after samp succeeds, even if exp becomes true later in the same cycle. Such race conditions should be avoided.

12-32

Preliminary

e Language Reference Manual

change(exp), fall(exp), rise(exp)

Temporal Expressions

Example 1
The following expression causes the event my_sel to be emitted on each occurrence of ev_clk where the bus addr_bus has the value dened as MY_ID.
event my_sel is true(addr_bus == MY_ID)@ev_clk;

See Also
Sampling Events Overview on page 11-9 Temporal Operators and Constructs on page 12-11

12.2.15 change(exp), fall(exp), rise(exp)


Purpose
Transition or edge temporal expression

Category
Temporal expression

Syntax
change | fall | rise(exp) [@event-type] Syntax example:
event hv_c is change(top.hold_var)@sim;

Parameters
exp event-type A Boolean expression, an integer expression, or an HDL object. The sampling event for the expression. Since change|rise|fall expressions are typically used to detect changes in HDL signals, the sampling event is often @sim.

Description
Detects a change in the sampled value of an expression.

e Language Reference Manual

Preliminary

12-33

Temporal Expressions

change(exp), fall(exp), rise(exp)

The behavior of each of the three temporal expressions (change, fall, and rise) is described in Table 12-2 on page 12-34. Table 12-2 Edge Condition Options Meaning Triggered when the expression changes from FALSE to TRUE. If it is an integer expression, the rise() temporal expression succeeds upon any change from x to y>x. Signals wider than one bit are allowed. Integers larger than 32 bits are not allowed. Triggered when the expression changes from TRUE to FALSE. If it is an integer expression, the fall() temporal expression succeeds upon any change from x to y<x. Signals wider than one bit are allowed. Integers larger than 32 bits are not allowed. Triggered when the value of the expression changes. The change() temporal expression succeeds upon any change of the expression. Signals wider than one bit are allowed. Integers larger than 32 bits are not allowed.

Edge Condition rise(exp)

fall(exp)

change(exp)

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. A special notation, @sim, can be used in place of a sampling event for rise, fall, or change of HDL objects. If @sim is used, the HDL object is watched by the simulator. The @sim notation does not signify an event, but is used only to cause a callback any time there is a change in the value of the HDL object to which it is attached. In a synchronous setting, such as a formal verication model, @sim is the same as @any. When a sampling event other than @sim is used, changes to the HDL object are detected only if they are visible at the sampling rate of the sampling event. In Figure 12-8 on page 12-35, evaluations of rise, fall, and change expressions for the HDL signal V are shown, with the sampling event @sim and with the sampling event @Q. The Q 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 Q. Since the signals value is the same at the third Q event as it was at the second Q event, the change('V')@Q expression does not succeed at the third Q event.

12-34

Preliminary

e Language Reference Manual

change(exp), fall(exp), rise(exp)

Temporal Expressions

Figure 12-8

Effects of the Sampling Rate on Detecting HDL Object Changes

'V' change('V')@sim rise('V')@sim fall('V')@sim Q change('V')@Q rise('V')@Q fall('V')@Q

When applied to HDL variables, the expressions examine the value after it is translated from the HDL four-value logic representation to a two-value logic representation. This causes the transition relations shown in Table 12-3 on page 12-35. Table 12-3 Transition Relations for HDL Variables Seen as not seen rise fall fall rise not seen

HDL value transition X->0 0->X X->1 1->X Z->0 0 ->Z Z->1 1->Z

Note
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;

e Language Reference Manual

Preliminary

12-35

Temporal Expressions

exec

Examples
The following denes 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 denes an event that occurs when the Boolean expression pkt_size > 20 changes from FALSE to TRUE:
event big_pkt is rise(pkt_size > 20);

See Also
Sampling Events Overview on page 11-9 Temporal Operators and Constructs on page 12-11

12.2.16 exec
Purpose
Attach an action block to a temporal expression, for simulation only.

Category
Temporal expression side effect

Syntax
temporal-expression exec action; ... Syntax example:
event @watcher_on is rise(top.watcher)@ev_clk exec { $display(%d,top.watch_val);};

Parameters
temporal-expression action The temporal expression that invokes the action block. A series of actions to perform when the expression succeeds.

12-36

Preliminary

e Language Reference Manual

Special Support for Model Checking

Temporal Expressions

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 tick.

Notes
The action block cannot contain any time-consuming actions. In a formal verication setting, the action block is ignored.

12.3 Special Support for Model Checking


12.3.1 Existential Path Quantier

For simulation environments, all temporal expressions in e are interpreted over the sequence of states traversed during simulation. Using this interpretation, temporal e is similar to Linear Temporal Logic. In a model checking environment, temporal e may be interpreted over all possible sequences (paths) starting from the circuit reset state. Under such interpretation, temporal e properties must hold on all paths. In other words, temporal e properties are always preceded by universal path quantiers by default. Additional expressiveness is added to the language by allowing the specication of properties that must hold on some paths (at least one path). This is achieved by the existential path quantier. Temporal expressions preceded by the existential path quantier are expected to hold on at least one path. Temporal expressions which are not preceded by the existential path quantier are expected to hold for all paths. Temporal expressions containing existential path quantiers are ignored in simulation contexts.

12.3.2
Purpose

exists(+)

Temporal expression existential path quantier, for model checking only.

e Language Reference Manual

Preliminary

12-37

Temporal Expressions

exists(+)

Category
Temporal path quantier.

Syntax
exists temporal-expression Syntax example:
expect @ev_x => exists eventually @ev_y;

Parameter
temporal-expA Temporal expression, which may include nested path quantiers.

Description
The temporal expression preceded by exists is expected to hold on some execution path (at least one). exists may precede any temporal expression. However, exists is not a temporal operator and may only be nested in the following contexts: Table 12-4 Context exp1 => exists exp2 expect exists exp Nesting contexts for exists Meaning On every paths where exp1 succeeds there must be at least one continuation where exp2 succeeds. There is a path in which exp is successful.

Example 1
module top; event clk is change(sysclk)@sim; event start_drive is rise(drive)@clk; event stop_drive is fall(drive)@clk; expect exists ({@stop_drive; @start_drive} @clk); // There is a back-to-back driving case endmodule

12-38

Preliminary

e Language Reference Manual

exists(+)

Temporal Expressions

Example 2
module top; event clk is rise(sysclk)@sim; event req is rise(reqline)@clk; event ack is fall(ackneg)@clk; expect { @req => exists @ack } @clk; // weak fairness - for every request there is a run that // will acknowledge endmodule

e Language Reference Manual

Preliminary

12-39

Temporal Expressions

exists(+)

12-40

Preliminary

e Language Reference Manual

13

Time-Consuming Actions

This chapter contains the following sections.

Synchronization Actions on page 13-1 Concurrency Actions on page 13-6

See Also
Invoking Methods on page 6-18 Chapter 11, Events Chapter 12, Temporal Expressions

13.1 Synchronization Actions


The following actions are used to synchronize temporal activities:

sync on page 13-2 wait on page 13-4

e Language Reference Manual

Preliminary

13-1

Time-Consuming Actions

sync

13.1.1
Purpose

sync

Synchronize an executing time-consuming method (TCM)

Category
Action

Syntax
sync [temporal-expression] Syntax example:
sent_data_tcm(); sync;

Parameters
temporal-expression A temporal expression that species 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 time step, the execution continues immediately. 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 time step. 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.

13-2

Preliminary

e Language Reference Manual

sync

Time-Consuming Actions

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 time step.

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 rst 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. 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(); }; }; '>

e Language Reference Manual

Preliminary

13-3

Time-Consuming Actions

wait

See Also
event on page 11-4 Sampling Events Overview on page 11-9 Chapter 12, Temporal Expressions wait on page 13-4

13.1.2
Purpose

wait

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 species what the time-consuming method (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 nd that it claries what the wait action does. The option has no effect on the results of the action. When a VHDL or Verilog simulator is linked to Specman Elite, the syntax wait delay(exp) can be used to wait for a specic simulation time period. Because not all simulators support delay values greater than 32 bits, the value of the expression in
13-4 Preliminary

e Language Reference Manual

wait

Time-Consuming Actions

wait delay(exp) cannot exceed 32 bits. A wait delay(exp) is inuenced by the timescale. See verilog time on page 15-9 and vhdl time on page 15-23 for more information on how Specman Elite 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. 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 specied). With a sync action, execution can continue immediately upon encountering the sync, if the temporal expression succeeds at that time See sync on page 13-2 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 [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

e Language Reference Manual

Preliminary

13-5

Time-Consuming Actions

Concurrency Actions

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; }; stop_run(); }; run() is also { start driver(); }; }; '>

See Also
event on page 11-4 Sampling Events Overview on page 11-9 Chapter 12, Temporal Expressions sync on page 13-2

13.2 Concurrency Actions


The actions that control concurrent execution of time-consuming methods (TCMs) are described in this section:

all of on page 13-7 rst of on page 13-8


Both of these actions create parallel action blocks which might start or call TCMs. The rst action awaits completion of all branches, while the second terminates at the rst completion of any branch.
13-6 Preliminary

e Language Reference Manual

all of

Time-Consuming Actions

Control of individual branches or TCMs can also be accomplished using predened methods of the predened scheduler struct.

13.2.1
Purpose

all of

Execute action blocks in parallel

Category
Action

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 nished:
all of { {check_bus_controller()}; {check_memory_controller()}; {check_alu()};

e Language Reference Manual

Preliminary

13-7

Time-Consuming Actions
};

first of

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"); }; }; '>

See Also
rst of on page 13-8

13.2.2
Purpose

rst of

Execute action blocks in parallel

Category
Action

Syntax
rst of {{action; }; } Syntax example:
first of { {wait [3]*cycle@ev_a}; {wait @ev_e; }; }; 13-8 Preliminary

e Language Reference Manual

first of

Time-Consuming Actions

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 rst of action will be reached when any of the branches in the rst of has been fully executed. All branches of the fork are automatically joined at the termination of the rst of action block. The parallel branches can be thought of as racing each other until one completes. Once one branch terminates, the execution of each of the other branches is also terminated. When two branches nish executing during the same cycle, it is not possible to determine which will prevail. One will complete successfully and the other will terminate.

Example 1
The rst 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 rst of actions can be used together to combine wait actions. In the following, the rst of action block terminates when event2 is seen:

e Language Reference Manual

Preliminary

13-9

Time-Consuming Actions

first of

<' 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(); }; }; '>

Example 3
In the following example, rst 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 nishes rst.
<' 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(); }; }; '>

13-10

Preliminary

e Language Reference Manual

first of

Time-Consuming Actions

See Also
all of on page 13-7

e Language Reference Manual

Preliminary

13-11

Time-Consuming Actions

first of

13-12

Preliminary

e Language Reference Manual

14

Coverage Constructs

This chapter contains the following sections:

Dening Coverage Groups on page 14-1 Dening Basic Coverage Items on page 14-7 Dening Cross Coverage Items on page 14-18 Dening Transition Coverage Items on page 14-23 Extending Coverage Groups on page 14-26

14.1 Defining Coverage Groups


14.1.1
Purpose
Dene a coverage group

cover

Category
Struct member

e Language Reference Manual

Preliminary

14-1

Coverage Constructs

cover

Syntax
cover event-type [using coverage-group-option, ...] is {coverage-item-denition; ...}; 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 dened previously in the struct. The event must not have been dened in a when construct. 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. coverage-groupoption The coverage group options listed in Table 14-1 can be specied 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-itemdenition empty The denition of a coverage item. Coverage items are described in Dening Basic Coverage Items on page 14-7. The second syntax, using the empty keyword, can be used to dene an empty coverage group that will be extended later, using another cover or cover is also struct member with the same name.

Table 14-1 Option no_collect

Coverage Group Options Description This coverage group is not displayed in coverage reports and is not saved in the coverage les.
Preliminary

14-2

e Language Reference Manual

cover

Coverage Constructs

Table 14-1 Option count_only text=string

Coverage Group Options (continued) Description Save the number of samples for each bucket of all items in the group. A text description for this coverage group. The coverage group is sampled only when bool-exp is TRUE. The bool-exp is evaluated in the context of the parent struct. A global coverage group is a group whose sampling event is expected to occur only once. If items from a global group are used in interactive cross coverage, no timing relationships exist between the items. Buckets for items of type int or uint are given the item value ranges as names.This option species 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.

when=bool-exp

global

radix=DEC|HEX|BIN

weight=uint

This option species the grading weight of the current group relative to other groups. It is a nonnegative integer with a default of 1.

Description
Denes a coverage group. A coverage group is struct member that contains a list of data items for which data is collected over time. Once coverage items have been dened in a coverage group, you can use them to dene special coverage group items called transition and cross items. See Dening Transition Coverage Items on page 14-23 and Dening Cross Coverage Items on page 14-18 for information about those coverage items.

e Language Reference Manual

Preliminary

14-3

Coverage Constructs

cover

The is keyword is used to dene a new coverage group. See Extending Coverage Groups on page 14-26 for information on using is also to extend an existing coverage group. Coverage groups should not be initially dened in when constructs, although they can be extended in when constructs.

Example 1
A coverage group named inst_driven is dened in the example below. The sampling event inst_driven is declared earlier in the same struct. The coverage group contains denitions 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 inst { opcode: cpu_opcode; op1: cpu_reg; op2: byte; event inst_driven; cover inst_driven is { item opcode; item op1; item op2; }; };

Example 2
The code below contains examples of the coverage group options.
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 using count_only is { item opcode; }; }; type memory_mode: [full, partial]; 14-4 Preliminary

e Language Reference Manual

cover

Coverage Constructs
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'; }; cover reset_event using global is { item memory; }; };

Example 3
The code below shows the radix coverage group option.
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; };

For the len item, the bucket names are: 0x0, 0x1, ... 0x7 (using the HEX radix specied for the group). For the data item, the bucket names are: [0x0..0x03], [0x04..0x07], ... [0xfc..0xff] (using the HEX radix specied 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.)

Example 4
The code below shows the weight coverage group option.
cover done using weight = 3 is { item len: uint (bits: 3) = sys.len; item data: byte = data; item mask; };

e Language Reference Manual

Preliminary

14-5

Coverage Constructs

cover

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.

Example 5
The code below shows how to use the empty coverage group keyword.
< struct inst { cover done is empty; }; > < extend inst { cover done is { item len: uint (bits: 3) = sys.len; item data: byte = data; item mask; }; }; >

Example 6
The code below shows how to dene coverage items in a when construct, by extending a coverage group dened previously but initially left empty.
< struct inst { size: [WIDE, REG]; event done; cover done is {}; }; > < extend inst { when WIDE inst { cover done is also { item len: uint (bits: 3) = sys.len; item data: byte = data; item mask; }; }; }; > 14-6 Preliminary

e Language Reference Manual

Defining Basic Coverage Items

Coverage Constructs

See Also
Dening Basic Coverage Items on page 14-7 Dening Cross Coverage Items on page 14-18 Dening Transition Coverage Items on page 14-23 Extending Coverage Groups on page 14-26 Chapter 11, Events Chapter 4, Structs, Fields and Subtypes

14.2 Defining Basic Coverage Items


14.2.1
Purpose
Dene a coverage item

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'; };

e Language Reference Manual

Preliminary

14-7

Coverage Constructs

item

Parameters
item-name The name you assign to the coverage item. If you do not specify the optional type=exp, the value of the eld named item-name is used as the coverage sample value. If you specify the optional type=exp, the value of the expression is used as the coverage sample value. type exp coverage-itemoption The type of the item. The type expression must evaluate to a scalar not larger than 32 bits, or a string. The expression is evaluated at the time the whole coverage group is sampled. This value is used for the item. Coverage item options are listed in Table 14-2. The options can appear in any order after the using keyword.

Table 14-2 Option no_collect text=string

Coverage Item Options Description This coverage item is not displayed in coverage reports and is not saved in the coverage les. A text description for this coverage item. The item is sampled only when bool-exp is TRUE. The bool-exp is evaluated in the context of the parent struct. The minimum number of samples for each bucket of the item. Anything less than num is considered a hole. This option cannot be used with string items or for unconstrained integer items (items that do not have specied ranges). You cannot specify a negative number. The default is 1.

when=bool-exp at_least=num

14-8

Preliminary

e Language Reference Manual

item

Coverage Constructs

Table 14-2 Option

Coverage Item Options (continued) Description 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 rst 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:

ranges = {range(parameters);}

range
The range for the bucket. It must be a literal range such as [1..5], of the proper type. Even a single value must be specied in brackets (for example [7]). If you specify ranges that overlap, values in the overlapping region go into the rst of the overlapping buckets. The specied 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. You must enter UNDEF for the every-count parameter.

every-count
The size of the buckets to create within the range. If you use the every-count parameter, you cannot use a name. You must enter an empty string () as a placeholder for the name parameter.

e Language Reference Manual

Preliminary

14-9

Coverage Constructs

item

Table 14-2 Option

Coverage Item Options (continued) Description

at-least-num
A number that species the minimum number of samples required for a bucket. If the item occurs 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. ignore=item-bool-exp Dene 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 the context of the struct, not in instances of the struct. Therefore, references to an instance of the struct are not allowed in the expression. For example, if i is a coverage item and j is a reference to a struct eld, the expression i > 5 is a valid expression, but i > me.j is not legal. illegal=item-bool-exp Dene values that are illegal. The Boolean expression is evaluated in the context of the struct, not in instances of the struct. Therefore, references to an instance of the struct are not allowed in the expression. For example, if i is a coverage item and j is a reference to a struct eld, the expression i > 5 is a valid expression, but i > me.j is not legal.

14-10

Preliminary

e Language Reference Manual

item

Coverage Constructs

Table 14-2 Option

Coverage Item Options (continued) Description For items of type int or uint, species 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 specied for an item, but a radix is specied for the items group, the groups radix applies to the item.

radix=DEC|HEX|BIN

no_trace weight=uint

This item will not be traced by the simulator. Species 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.

Description
Denes a new basic coverage item with an optional type. Options specify how coverage data is collected and reported for the item. The item can be an existing eld 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 denes it. If a value for an item falls outside all of the buckets for the item, that value does not count toward the items grade. The ranges option determines the number and size of buckets into which values for the item will be placed. If ranges is not specied, the default number of buckets is 16 (set by the max_int_buckets coverage conguration option). If buckets are not created for all possible values of the item, the values for which buckets do not exist are ungradeable. Those values are given goals of 0, and do not affect the grade for the item. For example, a randomly generated item of type uint has 232 -1 possible values. If no ranges are specied for a uint item, then buckets are created by default for only the rst 16 possible values (0 through 15). Since the odds
e Language Reference Manual
Preliminary 14-11

Coverage Constructs

item

that a uint value will be less than 16 are very small, it is almost certain that none of the values will fall into one of the 0 to 15 buckets, which are the only buckets for which a grade is calculated. This means that the item will not receive a grade, and will not contribute to the grade for the group. By default, basic items are enabled for echo event. You can use the no_trace option to disable tracing for an item. Below are some general examples of coverage item denitions. For examples of each of using the coverage item options, see Coverage Item Options Examples on page 14-12. Note Unless you turn on coverage mode, no coverage results are collected even if cover groups and items are dened. Use the cover conguration option to turn on coverage, as in the following example.
extend sys { setup() is also { set_config(cover, mode, normal); }; };

Coverage Item Options Examples


Examples of all the coverage item options are shown below. More examples of coverage item denitions are shown in Coverage Item Options Examples on page 14-12. no_collect example:
struct sm { cpu: top_cpu; event cs; cover cs is { item cb: bit = cpu.carry using no_collect; }; };

text example:
type state_name: [S1, S2]; struct sm { st: state_name; event state_change; cover state_change is { item st using text = "The CPU state"; }; }; 14-12 Preliminary

e Language Reference Manual

item

Coverage Constructs

when example:
type state_name: [S1, S2]; struct sm { cpu: top_cpu; st: state_name; event state_change; cover state_change is { item st using when = (cpu.init_complete == TRUE); }; };

at_least example:
type cpu_opcode: [ADD, SUB, OR, AND, JMP, LABEL]; struct inst { opcode: cpu_opcode; op1: byte; op2: byte; event inst_driven; cover inst_driven is { item op1; item op2; }; when JMP inst { op3: byte; cover inst_driven is also { item op3 using ranges = {range([0..255], "", 16)}, at_least = 10; }; }; };

The ranges option creates a bucket for each set of 16 values (0-15, 16 -31, ... , 240-255) for item op3. Any of those buckets for which fewer than 10 samples is collected is a hole. ranges example:
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");

e Language Reference Manual

Preliminary

14-13

Coverage Constructs
range([8k], "8k"); range([12k], "12k"); range([16k], "16k"); range([20k], "20k"); 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); }; }; };

item

The range specications 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). ignore example:
struct packet { len: uint (bytes: 2); 14-14 Preliminary

e Language Reference Manual

item
event xfer; cover xfer is { item len using ignore = (len > 32k); }; };

Coverage Constructs

Any len value greater than 32,768 is ignored. illegal example:


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], "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. The ranges option creates buckets for values from 16 to 4,096. radix example:
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 specied for this item). weight example:
cover done is { item len: uint (bits: 3) = packet_len;

e Language Reference Manual

Preliminary

14-15

Coverage Constructs
item data: byte = data; item mask using weight = 2; };

item

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. no_trace example:
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 echo event.

Additional Examples
The following example uses type=exp to dene coverage for a list element. In the b0 item denition, the type is byte and exp is b_list[0]. This collects coverage data for the value of the rst byte in b_list. This example also shows a predened list method, b_list.size(), used in the item denition 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(); }; };

The following example uses the type=exp parameter in the mem_mode item denition to dene coverage for a struct eld which is instantiated through a hierarchy of struct instances. The type is memory_type. The exp is the hierarchical path sys.cong.mem_type.
14-16 Preliminary

e Language Reference Manual

item

Coverage Constructs
struct mem { event mem_ch; cover mem_ch is { item mem_mode: memory_type = sys.config.mem_type; }; }; struct config { mem_type: memory_type; keep mem_type == top.mem_type; };

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 { 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] == 2b00); item opcode1: uint (bits: 2) = opcode using when = (opcode[15:14] == 2b01); item len; }; run() is also { emit fetch; }; };

See Also
Dening Coverage Groups on page 14-1 Dening Cross Coverage Items on page 14-18 Dening Transition Coverage Items on page 14-23 Dening Structs on page 4-3

e Language Reference Manual

Preliminary

14-17

Coverage Constructs

Defining Cross Coverage Items

14.3 Defining Cross Coverage Items


Cross items are combinations of items from the same coverage group. The cross coverage construct is used to dene cross items.

14.3.1
Purpose

cross

Dene 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; };

14-18

Preliminary

e Language Reference Manual

cross

Coverage Constructs

Parameters
item-name-1, item-name-2, ... Each item name must be one of the following.

the name of an item dened previously in the current


coverage group or the name of a transition item.

the name of a transition item dened previously in the


current coverage group coverage-itemoption An option for the cross item. The options are listed in Table 14-3.

Table 14-3 Option name=label text=string

Cross Coverage Item Options Description Species a name for a cross coverage item. No white spaces are allowed in the label. The default is cross__item-a__item-b. A text description for this coverage item. The item is sampled only when bool-exp is TRUE. The bool-exp is evaluated in the context of the parent struct. The minimum number of samples for each bucket of the item. Anything less than num is considered a hole. This option cannot be used with string items or for unconstrained integer items (items that do not have specied ranges). You cannot specify a number less than 1. The default is 1.

when=bool-exp at_least=num

ignore=item-bool-exp

The ignore expression denes values which are to be completely ignored. They do not appear in the statistics at all. The Boolean expression is evaluated in the context of the struct, not in instances of the struct. Therefore, references to an instance of the struct are not allowed in the expression. For example, if i is a coverage item and j is a reference to a struct eld, the expression i > 5 is a valid expression, but i > me.j is not legal.

e Language Reference Manual

Preliminary

14-19

Coverage Constructs

cross

Table 14-3 Option

Cross Coverage Item Options (continued) Description Dene values that are illegal. The Boolean expression is evaluated in the context of the struct, not in instances of the struct. Therefore, references to an instance of the struct are not allowed in the expression. For example, if i is a coverage item and j is a reference to a struct eld, the expression i > 5 is a valid expression, but i > me.j is not legal.

illegal=item-bool-exp

weight=uint

Species 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.

Description
Denes cross coverage between items in the same coverage group. Creates a new item with a name specied 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 rst and second items, and every combination of the third item and the rst item, the third item and the second item, and so on. You can cross any combination of basic coverage items and transitions dened in the same coverage group.

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. 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 denition 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 specied range.

14-20

Preliminary

e Language Reference Manual

cross

Coverage Constructs

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 rst by opcode value, by op1 under each opcode value, and by op2 under each op1 value.

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 denition, 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; }; };

e Language Reference Manual

Preliminary

14-21

Coverage Constructs

cross

Example 3
The example below shows how to dene 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 eld is assigned the value of the HDL req_type signal, by the exec expression. Thus, the request_type eld 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 denition 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 ranges = { range([0..3], "", 1); range(others, "invalid") }; item burst_mode: bool = top.burst_mode; cross request_type, burst_mode; }; };

See Also
Dening Coverage Groups on page 14-1 Dening Basic Coverage Items on page 14-7 Coverage Item Options Examples on page 14-12

14-22

Preliminary

e Language Reference Manual

Defining Transition Coverage Items

Coverage Constructs

14.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 dene transition items.

14.4.1
Purpose

transition

Dene a coverage transition item

Category
Coverage group item

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 coverage-itemoption A coverage item dened previously in the current coverage group. The coverage item options are listed in Table 14-4.

Table 14-4 Option

Transition Coverage Item Options Description Species a name for a transition coverage item. The default name is transition__item-name (where two underscores separate transition and item-name).

name=string

e Language Reference Manual

Preliminary

14-23

Coverage Constructs

transition

Table 14-4 Option text=string

Transition Coverage Item Options (continued) Description A text description for this coverage item. The item is sampled only when bool-exp is TRUE. The bool-exp is evaluated in the context of the parent struct. The minimum number of samples for each bucket of each of the cross items. Anything less than num is considered a hole. This option cannot be used with string items or for unconstrained integers (items that have no specied ranges). You cannot specify a negative number. The default is 1.

when=bool-exp at_least=num

ignore=item-bool-exp

Dene values that are to be completely ignored. They do not appear in the statistics at all. The Boolean expression is evaluated in the context of the struct, not in instances of the struct. Therefore, references to an instance of the struct are not allowed in the expression. For example, if i is a coverage item and j is a reference to a struct eld, the expression i > 5 is a valid expression, but i > me.j is not legal. The previous value can be accessed as prev_item-name. The prev prex is predened for this purpose.

illegal=item-bool-exp

Dene values that are illegal. The Boolean expression is evaluated in the context of the struct, not in instances of the struct. Therefore, references to an instance of the struct are not allowed in the expression. For example, if i is a coverage item and j is a reference to a struct eld, the expression i > 5 is a valid expression, but i > me.j is not legal. The previous value can be accessed as prev_item-name. The prev prex is predened for this purpose.

weight=uint

Species 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.

14-24

Preliminary

e Language Reference Manual

transition

Coverage Constructs

Description
Denes coverage for changes from one value to another of a coverage item. If no name is specied 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.

Note
If there is more than one instance of the struct that contains the coverage group, the transition coverage does not keep track of which old value goes with which new value.

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. 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 denition, st_change (transition st).
type cpu_state: [START, FETCH1, FETCH2, EXEC]; struct cpu { st: cpu_state; event state_change is

e Language Reference Manual

Preliminary

14-25

Coverage Constructs

Extending Coverage Groups

change('top.cpu.main_cur_state') @sim; cover state_change is { item st; transition st using name = st_change; }; };

See Also
Dening Coverage Groups on page 14-1 Dening Basic Coverage Items on page 14-7 Coverage Item Options Examples on page 14-12

14.5 Extending Coverage Groups


14.5.1
Purpose
Extend a coverage group

cover is also

Category
Struct member

Syntax
cover event-type is also {coverage-item-denition; ...} Syntax example:
cover rclk is also { item rflag; };

14-26

Preliminary

e Language Reference Manual

cover is also

Coverage Constructs

Parameters
event-type The name of the coverage group. This must be an event dened previously in the struct. The event is the sampling event for the coverage group. The denition of a coverage item.

coverage-itemdenition

Description
Adds new items to a coverage group.

Example
The following example extends a coverage group named info.
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; }; };

See Also
Dening Coverage Groups on page 14-1 Dening Basic Coverage Items on page 14-7

e Language Reference Manual

Preliminary

14-27

Coverage Constructs

cover is also

14-28

Preliminary

e Language Reference Manual

15

Simulation-Related Constructs

This chapter describes the following e constructs:

Verilog Statements or Unit Members on page 15-1 VHDL Statements and Unit Members on page 15-13 Simulation-Related Actions on page 15-24 Simulation-Related Expressions on page 15-27

15.1 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-specied declarations - verilog statements or unit members. The following sections describe these constructs:

verilog code on page 15-2 verilog function on page 15-3 verilog import on page 15-5 verilog task on page 15-7
e Language Reference Manual
Preliminary 15-1

Simulation-Related Constructs

verilog code

verilog time on page 15-9 verilog variable reg | wire on page 15-10 verilog variable memory on page 15-12

15.1.1
Purpose

verilog code

Write Verilog code directly to the stubs le

Category
Statement

Syntax
verilog code {string; } Syntax example:
verilog code {"initial clk = 1'b1;"};

Parameters
string Any legal Verilog string.

Description
Species a list of Verilog strings to be included in the Verilog stubs le each time it is generated. The stubs le contains code that enables some Verilog-related features.

Notes
verilog code statements cannot be used as unit members. Whenever you add or modify a verilog code statement in an e module, you must create
a new stubs le.

15-2

Preliminary

e Language Reference Manual

verilog function

Simulation-Related Constructs

Example 1
This example denes a clock in the Verilog stubs le:
verilog code { "reg clk;" ; " initial clk = 0;" ; "always #50 clk = ~clk;" ; };

15.1.2
Purpose

verilog function

Declare a Verilog function

Category
Statement or unit member

Syntax
verilog function 'HDL-pathname' (verilog-function-parameter[, ]): result-size: int; Syntax example:
verilog function 'top.write_mem'(addr:32, data:32):32;

e Language Reference Manual

Preliminary

15-3

Simulation-Related Constructs

verilog function

Parameters
HDL-pathname verilog-functionparameter The full path to the Verilog function. See 'HDL-pathname' on page 15-28 for a complete description of HDL path syntax. 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 compile-time constant specifying the size in bits of the parameter. No default size is assumed. result-size Species the width of the returned value.

Description
Declares a Verilog function in e so that it can be called from a time-consuming method (TCM).

Notes
Calls to Verilog functions are value-returning expressions. You must explicitly pack all structs before passing them in as inputs to the function. Whenever you add or modify a verilog function statement in an e module, you must
create a new stubs le and then load the le into the Verilog simulator.

Example
The following function has two 32-bit inputs and returns a 32-bit error status.
verilog function 'top.write_mem'(addr:32, data:32):32;

The memory_driver struct calls the top.write_mem() function.


struct memory_driver { event mem_enable is rise ('top.enable') @sim; write() @mem_enable is { var error_status: int; error_status = 'top.write_mem'(31,45); }; };

15-4

Preliminary

e Language Reference Manual

verilog import

Simulation-Related Constructs

See Also
'HDL-pathname' on page 15-28 Dening and Extending Methods on page 6-2

15.1.3
Purpose

verilog import

Read in Verilog text macros

Category
Statement

Syntax
verilog import le-name Syntax example:
verilog import defines_MCP.v;

Parameters
le-name The name of the le containing the Verilog text macros.

Description
Reads in a le that includes Verilog `dene text macros. After reading in the le, you can use these text macros in e expressions.

Notes
verilog import statements cannot be used as unit members. verilog import statements must appear in the e le before any other statement. Whenever you add or modify a verilog import statement in an e module, you need to
create a new stubs le and then load the le into the Verilog simulator if any of the imported Verilog macros appear in any verilog statements.
e Language Reference Manual
Preliminary 15-5

Simulation-Related Constructs

verilog import

For example, if you use a Verilog macro to specify the width of the parameters in a task identied with verilog task, then you need to recreate the stubs le if the macro is redened.

Example 1
You can use Verilog macros everywhere an e macro is allowed. For example, you can use Verilog macros in width declarations or when assigning values to enumerated items. macros.v
// 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 }; 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(); }; 15-6 Preliminary

e Language Reference Manual

verilog task
run() is also { start stimuli(); }; };

Simulation-Related Constructs

15.1.4
Purpose

verilog task

Declare a Verilog task

Category
Statement or unit member

Syntax
verilog task 'HDL-pathname' (verilog-task-parameter[, ]); Syntax example:
verilog task 'top.read'(addr: 64, cell: 128:out);

Parameters
HDL-pathname The full path to the Verilog task. See 'HDL-pathname' on page 15-28 for a complete description of HDL path syntax. 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 compile-time constant specifying the size in bits of the parameter. No default size is assumed. The direction is one of: input (or in), output (or out), inout. The default is input.
e Language Reference Manual
Preliminary 15-7

verilog-task-parameter

Simulation-Related Constructs

verilog task

Description
Declares a Verilog 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.
verilog task 'top.read'(addr: 64, cell: 128:out);

Notes
Calls to Verilog tasks are time-consuming actions and can only be made from TCMs. You must explicitly pack all structs before passing them in as inputs to the task. Whenever you add or modify a verilog task statement in an e module, you must create
a new stubs le and then load the le into the Verilog simulator.

Example
This task is similar to the Verilog function write_mem shown in the example for the verilog function statement (verilog function on page 15-3). This task returns an error status as an output parameter.
verilog task 'top.read_mem'(addr:32: in, data:64: out, status: 32: out); struct mem_w { addr: int; data: int(bits: 64); }; struct receiver { event mem_read_enable; get_mem(mw: mem_w) @mem_read_enable is { var error_status: int; 'top.read_mem'(mw.addr, mw.data, error_status); check that error_status == 0; }; };

See Also
'HDL-pathname' on page 15-28 Dening and Extending Methods on page 6-2
15-8 Preliminary

e Language Reference Manual

verilog time

Simulation-Related Constructs

15.1.5
Purpose

verilog time

Set the Verilog time resolution

Category
Statement

Syntax
verilog time verilog-time-scale Syntax example:
verilog time 100ns/10ns;

Parameters
verilog-time-scale The Verilog specication for time scale, time_unit/precision.

Description
Sets the time resolution in the Verilog stubs le to the specied verilog-time-scale.

Notes
verilog time statements cannot be used as unit members. Whenever you add or modify a verilog time statement in an e module, you must create
a new stubs le and then load the le into the Verilog simulator.

Example
verilog time 10ns/1ns;

e Language Reference Manual

Preliminary

15-9

Simulation-Related Constructs

verilog variable reg | wire

15.1.6
Purpose

verilog variable reg | wire

Identify a Verilog register or wire

Category
Statement or unit member

Syntax
verilog variable 'HDL-pathname' using option, Syntax example:
verilog variable 'top.dbus[5:0]' using wire, drive="@(posedge top.m)";

Parameters
HDL-pathname The complete path to the Verilog object, typically a register or a wire. See 'HDL-pathname' on page 15-28 for a complete description of HDL path syntax. A list of one or more of the following options separated by commas. Species that the Verilog object is driven when the event specied by string-exp occurs. string-exp is any legal Verilog timing control.

option drive=string-exp

drive_hold=string-exp Species a Verilog event after which the HDL objects value is set to z. string-exp is any legal Verilog timing control.The drive_hold option requires that you also specify the drive option. net or wire forcible strobe=string-exp Species that the Verilog object is a net (wire). Allows forcing of Verilog wires. By default Verilog wires are not forcible. Species that the value of the Verilog object is sampled at the event specied using string-exp. string-exp is any legal Verilog timing control.

15-10

Preliminary

e Language Reference Manual

verilog variable reg | wire

Simulation-Related Constructs

Description
Allows access from e to the Verilog object named in 'HDL-pathname', typically a register or a wire. In general, you can access Verilog objects using the 'HDL-pathname' expression. The verilog variable statement is necessary only when you want to

drive or force a wire drive or sample a wire or reg with an offset


verilog variable declarations can be repeated (to allow incremental building of e code), but each repeated declaration must be identical.

Notes
Whenever you add or modify a verilog variable statement in an e module, you must
create a new stubs le and then load the le into the Verilog simulator.

Example 1
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; on reset_request { 'top.reset_request' = 1; }; };

Example 2
The following example sets strobe and drive delays for a wire variable:
verilog variable 'top.xx_bus[63:0]' using strobe="@(posedge top.clk_b)", drive="@(negedge top.clk_b) #3", drive_hold="@(negedge top.clk_b) #10", wire;

See Also
'HDL-pathname' on page 15-28
e Language Reference Manual
Preliminary 15-11

Simulation-Related Constructs

verilog variable memory

force on page 15-24 release on page 15-26

15.1.7
Purpose

verilog variable memory

Identify a Verilog memory

Category
Statement or unit member

Syntax
verilog variable 'HDL-pathname [mem-range] [verilog-reg-range]' Syntax example:
verilog variable 'top.my_mem[1:10000][31:0]';

Parameters
HDL-pathname mem-range verilog-reg-range The full path to the Verilog memory. See 'HDL-pathname' on page 15-28 for a complete description of HDL path syntax. The range of the memory elements. The width of each memory element.

Description
Allows access from e to a Verilog memory. verilog variable declarations can be repeated (to allow incremental building of e code), but each repeated declaration must be identical. Note that the order of the range speciers in e is the reverse of the Verilog declaration order. For example, if a memory is dened in Verilog as follows:
module top; reg[31:0] my_mem[1:10000]; endmodule 15-12 Preliminary

e Language Reference Manual

VHDL Statements and Unit Members

Simulation-Related Constructs

The corresponding verilog variable statement is:


verilog variable 'top.my_mem[1:10000][31:0]';

Notes
Whenever you add or modify a verilog variable statement in an e module, you must
create a new stubs le and then load the le into the Verilog simulator.

See Also
'HDL-pathname' on page 15-28

15.2 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-specied declarations - vhdl statements. The following sections describe these statements and unit members:

vhdl code on page 15-13 vhdl driver on page 15-15 vhdl function on page 15-17 vhdl procedure on page 15-20 vhdl time on page 15-23

15.2.1
Purpose

vhdl code

Write VHDL code directly to the stubs le

Category
Statement

e Language Reference Manual

Preliminary

15-13

Simulation-Related Constructs

vhdl code

Syntax
vhdl code {string; } Syntax example:
vhdl code { "library common_lib;"; "use common_lib.common_types.all;"; };

Parameters
string Any legal VHDL string.

Description
Species a list of VHDL strings to be included in the stubs le. The stubs le contains code that enables some simulation-related features.

Notes
vhdl code statements cannot be used as unit members. Whenever you add or modify a vhdl code statement in an e module, you must create a
new stubs le.

Example
The example below adds the common_types package dened in the common_lib library to the stubs le.
vhdl code { "library common_lib;"; "use common_lib.common_types.all;"; };

See Also
VHDL Statements and Unit Members on page 15-13

15-14

Preliminary

e Language Reference Manual

vhdl driver

Simulation-Related Constructs

15.2.2
Purpose

vhdl driver

Drive a VHDL signal continuously via the resolution function

Category
Unit member

Syntax
vhdl driver 'HDL-pathname' using option, Syntax example:
vhdl driver '~/top/data' using initial_value=32'bz, disconnect_value=32'bz;

Parameters
HDL-pathname A full or a relative VHDL path to the signal. If the signal has more than one driver, then the signal must be of a resolved type. See 'HDL-pathname' on page 15-28 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.

disconnect_value= Species the value to be used to disconnect the driver. The [constant-expression | default is z. verilog-literal] 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. delay= numeric-expression Species a delay for all assignments. The delay time units are determined by the current time unit setting. See vhdl time on page 15-23 for information on how to set time units.

e Language Reference Manual

Preliminary

15-15

Simulation-Related Constructs

vhdl driver

mode=[INERTIAL | Used only when delay is also specied, this option TRANSPORT] species whether pulses whose period is shorter than the delay are propagated through the driver. INERTIAL, the default, species that such pulses are not propagated. TRANSPORT species that all pulses, regardless of length, are propagated. The mode option also inuences 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 rst change never occurs. initial_value= Species a value to initialize the signal to. [constant-expression | Use a Verilog literal to specify values containing x or z. A verilog-literal] Verilog literal is a sized literal that can contain 0, 1, x, and z, for example 16'bx.

Description
The vhdl driver unit member identies a VHDL signal that, when assigned to by an e method, is driven continuously using the resolution function. 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 inuences any assignments to the specied 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 tristate bus, for example. Multiple drivers can be created only for signals of a resolved type.

Notes
vhdl driver cannot be used as a statement because it inuences only assignments made
in methods of the enclosing unit or of the structs enclosed by this unit.

The vhdl driver unit member does not affect the VHDL stubs le, so it is not necessary
to rewrite the stubs le if you add or modify a vhdl driver unit member in your e code.
15-16 Preliminary

e Language Reference Manual

vhdl function

Simulation-Related Constructs

Example
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 drive1.hdl_path() == "~/top" ; }; unit drive { vhdl driver ~/top/t using disconnect_value = 1bz, initial_value = 1bz ; driver() @sys.clk is { ~/top/t = 1 ; wait cycle ; ~/top/t = 1bz ; wait [7] ; ~/top/t = 0 ; wait cycle ; stop_run() ; }; run() is also { start driver() } ; }; >

See Also
'HDL-pathname' on page 15-28 VHDL Statements and Unit Members on page 15-13

15.2.3
Purpose

vhdl function

Declare a VHDL function dened in a VHDL package

e Language Reference Manual

Preliminary

15-17

Simulation-Related Constructs

vhdl function

Category
Statement or unit member

Syntax
vhdl function 'designator' using option, Syntax example:
vhdl function 'max' using interface="(op1:word64; op2:word64) return word64", library="work", package="arith_pkg";

Parameters
designator option The operator symbol (for example '"and') or the name of the VHDL function as specied in the package. A comma-separated list of two or more of the following options. The interface, library and package options are required. The syntax for interface-list is [parameter-class] identier :subtype[;] The only output of the function is the returned value. The optional parameter class is constant or signal as specied in the VHDL declaration. The identier does not have to be the name of the parameter as specied in the package but the parameter subtype must match exactly the package specication. The type of the returned value must match exactly the package specication. library=library-name A string specifying the name of the VHDL library containing the package where the function is dened.

interface= (interface-list) return return-subtype

15-18

Preliminary

e Language Reference Manual

vhdl function

Simulation-Related Constructs

package= primary-unit-name alias=alias-name declarative_item=items

A string specifying the package name. A string that species the name with which the function will be called from e. A string that species one or more use clauses that are placed in the stubs le at the local scope of the function call.

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
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.

Whenever you add or modify a vhdl function statement in an e module, you must create
a new stubs le.

Example 1
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;

e Language Reference Manual

Preliminary

15-19

Simulation-Related Constructs

vhdl procedure

test(a:int)@clk is { check that 'integer_inc_1'(a) == 'integer_inc_n'(a,1); }; };

See Also
'HDL-pathname' on page 15-28 VHDL Statements and Unit Members on page 15-13

15.2.4
Purpose

vhdl procedure

Declare a VHDL procedure dened in a VHDL package

Category
Statement or unit member

Syntax
vhdl procedure 'identier' using option, Syntax example:
vhdl procedure 'do_arith_op' using interface="(op1:integer; op2: integer; \ op_code: func_code; result: out integer)", \ library="work", package="arith_pkg";

15-20

Preliminary

e Language Reference Manual

vhdl procedure

Simulation-Related Constructs

Parameters
identier option interface= (interface-list) The name of the VHDL procedure as specied in the package. A comma-separated list of two or more of the following options. The library and package options are required. The syntax for interface-list is [ parameter_class ] identier : [mode] subtype[;] The optional parameter class is constant, variable, or signal as dened in the VHDL declaration. Mode is in, inout or out. The default mode is in. The identier does not have to be the name of the parameter as specied in the package but the subtype must match exactly the specication in the package. library= library-name package= primary-unit-name alias= alias-name declarative_item= items A string specifying the name of the library containing the package where the procedure is dened. A string specifying the package name. A string that species the name with which the procedure will be called from e. A string that species a use clause that is placed at the local scope of the procedure call.

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.

e Language Reference Manual

Preliminary

15-21

Simulation-Related Constructs

vhdl procedure

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 immediately but are not forced and not assigned via a VHDL driver.

Notes
Calls to VHDL procedures are time-consuming and can only be made from TCMs. 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.

Whenever you add or modify a vhdl procedure statement in an e module, you must
create a new stubs le.

Example 1
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", package="display_pkg", declarative_item="use lib2.widget_types.all;";

See Also
'HDL-pathname' on page 15-28 VHDL Statements and Unit Members on page 15-13

15-22

Preliminary

e Language Reference Manual

vhdl time

Simulation-Related Constructs

15.2.5
Purpose

vhdl time

Sets VHDL time resolution

Category
Statement

Syntax
vhdl time constant-exp time-unit Syntax example:
vhdl time 100 ns;

Parameters
constant-exp time-unit An expression that evaluates to a constant at run time. Any valid VHDL time unit.

Description
Sets the time resolution to the specied time scale.

Notes
The vhdl time statement does not affect the stubs le, so it is not necessary to rewrite
the stubs le if you change the time scale.

vhdl time cannot be used as a unit member.

Example
The following statement sets the time resolution to 100ns.
vhdl time 100 ns;

e Language Reference Manual

Preliminary

15-23

Simulation-Related Constructs

Simulation-Related Actions

See Also
VHDL Statements and Unit Members on page 15-13 vhdl driver on page 15-15

15.3 Simulation-Related Actions


There are two simulation-related actions in e:

force on page 15-24 release on page 15-26

15.3.1
Purpose

force

Force a value on an HDL object

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 15-28 for more information. 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.

exp

15-24

Preliminary

e Language Reference Manual

force

Simulation-Related Constructs

Description
Forces an HDL object to a specied value, overriding the current value and preventing the DUT from driving any value. The HDL object remains at the specied value until a subsequent force action from e or until freed by a release action.

Example 1
struct sim { event clk is rise (~/top/clk)@sim; m() @clk is { ~/top/data = 8b10101010; force ~/top/data[3:0] =0; ~/top/data[7:4] = 4b0000; wait cycle; ~/top/data = 8b10011001; wait cycle; release ~/top/data[7:0]; wait cycle; ~/top/data = 8b11111111; wait [2]* cycle; stop_run(); }; }; extend sys { sim;

run() is also { start sys.sim.m(); }; };

verilog.e
verilog variable ~/top/data[7:0] using wire, forcible;

e Language Reference Manual

Preliminary

15-25

Simulation-Related Constructs

release

See Also
'HDL-pathname' on page 15-28 release on page 15-26

15.3.2
Purpose

release

Remove a force action from an HDL object

Category
Action

Syntax
release 'HDL-pathname' Syntax example:
release 'TOP.sig';

Parameters
HDL-pathname The full path name of an HDL object previously specied in a force action.

Description
Releases the HDL object that you have previously forced.

Example 1
struct sim { event clk is rise (~/top/clk)@sim; m() @clk is { ~/top/data = 8b10101010; force ~/top/data[3:0] =0; ~/top/data[7:4] = 4b0000; 15-26 Preliminary

e Language Reference Manual

Simulation-Related Expressions
wait cycle; ~/top/data = 8b10011001; wait cycle; release ~/top/data[7:0]; wait cycle; ~/top/data = 8b11111111; wait [2]* cycle; stop_run(); }; }; extend sys { sim;

Simulation-Related Constructs

run() is also { start sys.sim.m(); }; };

verilog.e
verilog variable ~/top/data[7:0] using wire, forcible;

See Also
'HDL-pathname' on page 15-28 force on page 15-24

15.4 Simulation-Related Expressions


This section contains:

'HDL-pathname' on page 15-28

e Language Reference Manual

Preliminary

15-27

Simulation-Related Constructs

'HDL-pathname'

15.4.1
Purpose

'HDL-pathname'

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';

Parameters
HDL-path-name bit-range The full path name of an HDL object, optionally including expressions and composite data. 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 specied in the same direction as in the HDL code and reference the same bit numbers. Accesses a single bit of a Verilog vector, a single element of a Verilog memory, or a single element of a VHDL array of arrays. Sets or gets the x or z component of the value. When this notation is not used in accessing an HDL object, the value of x is translated to zero and z to one. When this specier is used for driving HDL objects, the new value is visible immediately (now).

index-exp @x | z

@n

Description
Accesses Verilog and VHDL objects from e.

15-28

Preliminary

e Language Reference Manual

'HDL-pathname'

Simulation-Related Constructs

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.

e Language Reference Manual

Preliminary

15-29

Simulation-Related Constructs

'HDL-pathname'

15-30

Preliminary

e Language Reference Manual

16

Packing and Unpacking

Packing performs concatenation of scalars, strings, list elements, or struct elds 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)
For type conversion, e 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 4-25 in e Libraries. Recommended for converting a single scalar to a list of bit. For more information, see Chapter 2, e Basics.

sublisting with [..]

e Language Reference Manual

Preliminary

16-1

Packing and Unpacking

Basic Packing

bit extraction with [:] unpacking packing

Recommended for converting a list of bit into a single scalar. For more information, see Chapter 2, e Basics. Recommended for converting from a list of bit to strings, lists, structs, or multiple scalars. Recommended for all other purposes.

This chapter contains the following sections

Basic Packing on page 16-2 Advanced Packing on page 16-12

16.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 the two basic packing methods, pack() and unpack().

A Simple Example of Packing on page 16-3 A Simple Example of Unpacking on page 16-5 Packing and Unpacking Scalar Expressions on page 16-6 Packing and Unpacking Strings on page 16-8 Packing and Unpacking Structs on page 16-9 Packing and Unpacking Lists on page 16-10
For information on two other basic tools for packing, see

%{} on page 2-64 swap() on page 4-47 in e Libraries

See Also
Advanced Packing on page 16-12 Constructs for Packing and Unpacking on page 4-37 in e Libraries

16-2

Preliminary

e Language Reference Manual

A Simple Example of Packing

Packing and Unpacking

16.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 dened as:
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; };

The examples below show how to pack the opcode and the operand elds into two variables. The order in which the elds 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 signicant bit of the rst expression in pack(), opcode, is placed at index [0] in the resulting list of bit. The most signicant bit of the last expression, operand, is placed at the highest index in the resulting list of bit. Figure 16-1 on page 16-4 shows this packing order. packing.low is the default packing order.

e Language Reference Manual

Preliminary

16-3

Packing and Unpacking

A Simple Example of Packing

Figure 16-1

Simple Packing Example Showing packing.low

The instruction struct with two elds: opcode == 0x4 operand == 0x19 1 0 1 0 0 1

1 0

The two elds packed into a bit stream, using the default ordering operand 1 1 0 0 1 opcode 1 0 0

list of bit [7]

list of bit [0]

With packing.high, the least signicant bit of the last expression, operand, is placed at index [0] in the resulting list of bit. The most signicant bit of the rst expression, opcode, is placed at the highest index in the resulting list of bit. Figure 16-2 shows this packing order. Figure 16-2 Simple Packing Example Showing packing.high

The instruction struct with two elds: opcode == 0x4 operand == 0x19 1 0 1 0 0 1

1 0

The two elds packed into a bit stream, using the packing.high ordering opcode 1 0 0 1 operand 1 0 0 1

list of bit [7]

list of bit [0]

16-4

Preliminary

e Language Reference Manual

A Simple Example of Unpacking

Packing and Unpacking

Pack expressions, like the ones shown in the example above, are untyped expressions. See Untyped Expressions on page 3-13 for more information.

See Also
A Simple Example of Unpacking on page 16-5 Packing and Unpacking Scalar Expressions on page 16-6 Packing and Unpacking Strings on page 16-8 Packing and Unpacking Structs on page 16-9 Packing and Unpacking Lists on page 16-10

16.1.2

A Simple Example of Unpacking

This example shows how packing lls the elds of a struct instance with data from a bit stream. An instruction struct is dened as:
struct instruction { %opcode : uint (bits : 3); %operand : uint (bits : 5); %address : uint (bits : 8); };

The example 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 16-3.
extend sys { pack_data() is { 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); }; };

e Language Reference Manual

Preliminary

16-5

Packing and Unpacking

Packing and Unpacking Scalar Expressions

Figure 16-3

Simple Unpacking Example Showing packing.high

The packed data 1 0 0 1 1 0 0 1 0 0 0 0 1 1 1 1

The result of unpacking the data with packing.high:

opcode == 0x4 operand == 0x19 address == 0x0f

1 0 1 0

0 0 1 0 1 1 1 1

1 0 0 0

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, implicit packing is required to store the data in the target expression. See Implicit Packing and Unpacking on page 16-24 for more details.

See Also
A Simple Example of Packing on page 16-3 Packing and Unpacking Scalar Expressions on page 16-6 Packing and Unpacking Strings on page 16-8 Packing and Unpacking Structs on page 16-9 Packing and Unpacking Lists on page 16-10

16.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 lls the scalar expression, starting by default by putting the lowest bit of the bit stream into the lowest bit of the scalar expression.

16-6

Preliminary

e Language Reference Manual

Packing and Unpacking Scalar Expressions

Packing and Unpacking

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 Overview of e Data Types on page 3-1 for information on how the size of a scalar expression is determined. See also Bit Slice Operator and Packing on page 16-23.

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 rst ve 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 int_5 = 31 int_2 = 1 0 0 1 1 .0

Note Unpacking a list into one or more scalar expressions where are not enough bits in the list to put a value into each scalar is illegal.

See Also
A Simple Example of Packing on page 16-3 A Simple Example of Unpacking on page 16-5 Packing and Unpacking Strings on page 16-8 Packing and Unpacking Structs on page 16-9 Packing and Unpacking Lists on page 16-10

e Language Reference Manual

Preliminary

16-7

Packing and Unpacking

Packing and Unpacking Strings

16.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 nal NULL byte). Unpacking a string places the bytes of the string into the target expression, starting with the rst ASCII byte in the string up to and including the rst 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 4-25 in e Libraries 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 nal 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 my_list_of_byte = (4 items, hex): 00 43 42 41 .0 4 2 4 1 .0

See Also
A Simple Example of Packing on page 16-3 A Simple Example of Unpacking on page 16-5 Packing and Unpacking Scalar Expressions on page 16-6 Packing and Unpacking Structs on page 16-9 Packing and Unpacking Lists on page 16-10

16-8

Preliminary

e Language Reference Manual

Packing and Unpacking Structs

Packing and Unpacking

16.1.5

Packing and Unpacking Structs

Packing a struct creates an ordered bit stream from all the physical elds (marked with %) in the struct, starting by default with the rst physical eld declared. Other elds (called virtual elds) are ignored by the packing process. If a physical eld 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 lls the physical elds of the struct, starting by default with the rst eld declared and proceeding recursively through all the physical elds of the struct. Unpacking a bit stream into a eld that is a list follows some additional rules described in Packing and Unpacking Lists on page 16-10. A struct is packed or unpacked using its predened methods do_pack() and do_unpack(). It is possible to modify these predened methods for a particular struct. See do_pack() on page 4-49 and do_unpack() on page 4-53 in e Libraries for more information.

Example
This example packs the two physical elds in my_struct into the variable ms. The resulting bit stream is 14 bits, which is exactly the combination of both the physical elds. The virtual eld 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; }; };

Result
pack(packing.low,ms) = (14 items, bin): 0 0 0 0 0 0 1 1 1 1 0 0 1 1 .0

e Language Reference Manual

Preliminary

16-9

Packing and Unpacking

Packing and Unpacking Lists

See Also
A Simple Example of Packing on page 16-3 A Simple Example of Unpacking on page 16-5 Packing and Unpacking Scalar Expressions on page 16-6 Packing and Unpacking Strings on page 16-8 Packing and Unpacking Lists on page 16-10

16.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 lls 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 lls the sized lists only to their dened 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 dened size is reached. See Chapter 2, e Basics, for more information on sizing lists.

Example 1
This rst 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 9 7 5 3 .0

16-10

Preliminary

e Language Reference Manual

Packing and Unpacking Lists

Packing and Unpacking

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 0 0 0 0 0 5 .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 0 5 .0

Example 4
The my_list eld 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; }; };

e Language Reference Manual

Preliminary

16-11

Packing and Unpacking

Advanced Packing

Result
t.my_list = (empty) t.my_list = (4 items, hex): 0 0 0 5 .0

See Also
A Simple Example of Packing on page 16-3 A Simple Example of Unpacking on page 16-5 Packing and Unpacking Scalar Expressions on page 16-6 Packing and Unpacking Strings on page 16-8 Packing and Unpacking Structs on page 16-9

16.2 Advanced Packing


The following sections describe how to use advanced packing features and provide you with the concepts you need to use them efciently:

Using the Predened pack_options Instances on page 16-13 Customizing Pack Options on page 16-19 Customizing Packing for a Particular Struct on page 16-23 Bit Slice Operator and Packing on page 16-23 Implicit Packing and Unpacking on page 16-24 Untyped Expressions on page 3-13

See Also
Basic Packing on page 16-2 Constructs for Packing and Unpacking on page 4-37 in e Libraries

16-12

Preliminary

e Language Reference Manual

Using the Predefined pack_options Instances

Packing and Unpacking

16.2.1

Using the Predened pack_options Instances

Packing and unpacking are controlled using a struct under global named packing. There are ve predened instances of the pack_options struct that you can use with or without modication 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 predened pack_options instances as the rst 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 16-13 packing.low_big_endian on page 16-14 packing.high on page 16-15 packing.high_big_endian on page 16-16 packing.network on page 16-17 packing.global_default on page 16-18

See Also
Customizing Pack Options on page 16-19 Customizing Packing for a Particular Struct on page 16-23 Bit Slice Operator and Packing on page 16-23 Implicit Packing and Unpacking on page 16-24 Untyped Expressions on page 3-13

16.2.1.1 packing.low
This pack_options instance traverses the source elds or variables in the order they appear in code, placing the least signicant bit of the rst eld or list item at index [0] in the resulting list of bit. The most signicant bit of the last eld or list item is placed at the highest index in the resulting list of bit.
e Language Reference Manual
Preliminary 16-13

Packing and Unpacking

Using the Predefined pack_options Instances

<' 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; pack_data() is { data_packed_low = pack(packing.low, me); print me using bin; print data_packed_low using bin; }; }; '>

Result
me = instruction-@0: instruction 0 1 2 3 @packing20 %opcode: 0b100 %operand: 0b11001 %address: 0b00001111 !data_packed_low: (16 items) 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 Predened pack_options Instances on page 16-13

16.2.1.2 packing.low_big_endian
This pack_options instance, like packing.low, traverses the source elds or variables in the order they appear in code. In addition, for every scalar eld or variable, it

Swaps every byte in each pair of bytes Swaps every two bytes in each 32-bit word
Note If the scalars width is not a multiple of 16, no swapping is performed

16-14

Preliminary

e Language Reference Manual

Using the Predefined pack_options Instances

Packing and Unpacking

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): 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 .0 .24

i_stream = (36 items, bin): 1 1 1 1 0 1 0 1 0 1 0 1

1 1 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1

.0 .24

See Also

Using the Predened pack_options Instances on page 16-13

16.2.1.3 packing.high
This pack_options instance traverses the source elds or variables in the reverse order from the order in which they appear in code, placing the least signicant bit of the last eld or list item at index [0] in the resulting list of bit. The most signicant bit of the rst eld or list item is placed at the highest index in the resulting list of bit.
<' struct instruction { %opcode : uint (bits : 3);

e Language Reference Manual

Preliminary

16-15

Packing and Unpacking


%operand %address

Using the Predefined pack_options Instances


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

!data_packed_high : list of bit; keep opcode == 0b100; keep operand == 0b11001; keep address == 0b00001111; pack_data() is { 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: data_packed_high = (8 items, bin): 0b100 0b11001 0b00001111 (8 items) 1 0 0 1 1 0 0 1 .0

See Also

Using the Predened pack_options Instances on page 16-13

16.2.1.4 packing.high_big_endian
This pack_options instance, like packing.high, traverses the source elds or variables in the reverse order from the order in which they appear in code. In addition, for every scalar eld or variable, it

Swaps every byte in each pair of bytes Swaps every two bytes in each 32-bit word
Note If the scalars width is not a multiple of 16, no swapping is performed. The example below shows the difference between packing.high and packing.high_big_endian.
16-16 Preliminary

e Language Reference Manual

Using the Predefined pack_options Instances


struct pac { %opcode: uint (bits:4); %operand1: uint (bytes:2); %operand2: uint (bytes:2); keep opcode == 0xf; keep operand1 == 0xcc55; keep operand2 == 0xff00;

Packing and Unpacking

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): 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 0 0 .0 .24

i_stream = (36 items, bin): 1 1 0 0 1 1 0 0 0 0 0 0

0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1

.0 .24

See Also

Using the Predened pack_options Instances on page 16-13

16.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;

e Language Reference Manual

Preliminary

16-17

Packing and Unpacking

Using the Predefined pack_options Instances

!data_packed_network : list of bit; keep opcode == 0b100; keep operand == 0b11001; keep address == 0b00001111; pack_data() is { 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
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 data_packed_network = (16 items, bin): 0 0 0 0 1 1 1 1 1 0 0 1

.0

1 0 0 1

.0

16.2.1.6 packing.global_default
This pack_options instance is used when the rst parameter of pack(), unpack(), do_pack(), or do_unpack() is NULL. It has the same ags as packing.low. See Also

Using the Predened pack_options Instances on page 16-13

16-18

Preliminary

e Language Reference Manual

Customizing Pack Options

Packing and Unpacking

16.2.2

Customizing Pack Options

Each of the predened instances described in Using the Predened pack_options Instances on page 16-13 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 elds, and pass the struct instance as the rst parameter to pack(), unpack(), do_pack(), or do_unpack(). The following sections describe each eld of the pack_options struct:

reverse_elds on page 16-19 reverse_list_items on page 16-20 scalar_reorder on page 16-21 nal_reorder on page 16-22

See Also
Using the Predened pack_options Instances on page 16-13 Customizing Packing for a Particular Struct on page 16-23 Bit Slice Operator and Packing on page 16-23 Implicit Packing and Unpacking on page 16-24 Untyped Expressions on page 3-13

16.2.2.1 reverse_fields
If this ag is set to be FALSE, the elds 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.

e Language Reference Manual

Preliminary

16-19

Packing and Unpacking

Customizing Pack Options

Example When reverse_elds is FALSE, rst is packed and then second. When the ag is set to TRUE, second is packed before rst. Thus, the rst 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 pack(p2,my_struct) = (2 items, hex): 2 .0 .0

See Also

Customizing Pack Options on page 16-19

16.2.2.2 reverse_list_items
If this ag 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}; 16-20 Preliminary

e Language Reference Manual

Customizing Pack Options


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;

Packing and Unpacking

Result
pack(p1,my_list) = (3 items, bin): 0 0 1 pack(p2,my_list) = (3 items, bin): 1 0 0 .0 .0

See Also

Customizing Pack Options on page 16-19

16.2.2.3 scalar_reorder
You can perform some swap() operations on each scalar before packing using the scalar_reorder eld. Each pair of items in the list is a parameter in a swap() operation. Note The list in the scalar_reorder eld must include an even number of items. Example Before mid and sma are packed, the bits are swapped using 4 and 2 as parameters. (See swap() on page 4-47 in e Libraries.) Thus, within every four bits the rst 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 pack(p1,sma) = (4 items, bin): 0 1 1 0 .0 16-21 1 1 0 0 .0

e Language Reference Manual

Preliminary

Packing and Unpacking

Customizing Pack Options

pack(p1,mid) = (8 items, bin): 0 0 1 1 pack(p1,sma) = (4 items, bin): 1 0 0 1 .0 0 0 1 1 .0

See Also

Customizing Pack Options on page 16-19

16.2.2.4 final_reorder
After packing each element in the packing expression you can perform nal swapping on the resulting bit stream. This can be done using the nal_reorder eld. Note The list in the nal_reorder eld must include an even number of items. Example After performing the second pack, a swap is performed using 4 and 8 as parameters.
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 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

.0

See Also

Customizing Pack Options on page 16-19

16-22

Preliminary

e Language Reference Manual

Customizing Packing for a Particular Struct

Packing and Unpacking

16.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 4-49 and do_unpack() on page 4-53 in e Libraries for more information.

See Also
Using the Predened pack_options Instances on page 16-13 Customizing Pack Options on page 16-19 Bit Slice Operator and Packing on page 16-23 Implicit Packing and Unpacking on page 16-24 Untyped Expressions on page 3-13

16.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 rst 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 ve 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.
e Language Reference Manual
Preliminary 16-23

Packing and Unpacking

Implicit Packing and Unpacking

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 Predened pack_options Instances on page 16-13 Customizing Pack Options on page 16-19 Customizing Packing for a Particular Struct on page 16-23 Implicit Packing and Unpacking on page 16-24 Untyped Expressions on page 3-13

16.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 3-13 for more information.

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};

When the value expression of an unpack action is other than a list of bit, it is implicitly
packed before it is unpacked:

16-24

Preliminary

e Language Reference Manual

Implicit Packing and Unpacking


unpack(packing.low,5,my_list);

Packing and Unpacking

See Also
Using the Predened pack_options Instances on page 16-13 Customizing Pack Options on page 16-19 Customizing Packing for a Particular Struct on page 16-23 Bit Slice Operator and Packing on page 16-23 Untyped Expressions on page 3-13

e Language Reference Manual

Preliminary

16-25

Packing and Unpacking

Implicit Packing and Unpacking

16-26

Preliminary

e Language Reference Manual

17

Preprocessor Directives

This chapter contains the following sections:

dene on page 17-2. You use this construct to dene name macros in e. #ifdef, #ifndef on page 17-4. You use these preprocessor directives used to control
e processing. The preprocessor directives check for the existence of a dene for a given name:

#ifdef directive: if a given name is dened, use the attached code, otherwise, use
different code

#ifndef: if a given name is not dened, use the attached code, otherwise, use
different code The #ifdef and #ifndef directives can be used as statements, struct members, or actions.

See Also
Chapter 18, Importing e Files

e Language Reference Manual

Preliminary

17-1

Preprocessor Directives

define

17.1 dene
Purpose
Dene a name macro

Category
Statement

Syntax
dene [`]name: macro-name [replacement] Syntax example:
define PLIST_SIZE 100;

Parameters
name Any e name. This is used with no replacement parameter for conditional code processing. An #ifdef preprocessor directive later in the e code that has the name as its argument evaluates to TRUE. When a replacement is given, the parser substitutes the replacement for the macro name everywhere name appears, except inside strings. The name can be preceded with a backtick, `. This makes the name look like a Verilog `dene 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. This replaces the name wherever the name appears in the e code that follows the dene statement.

Note
Be sure to use parentheses around the replacement when they are needed to ensure proper associativity. For example, the effect of:
define LX 2*len+m; 17-2 Preliminary

e Language Reference Manual

define

Preprocessor Directives

Is different from the effect of:


define LX 2*(len+m);

In an expression like lenx = LX, the rst case becomes lenx = 2*len + m, while the second case becomes lenx = 2*len + 2*m.

Description
With a replacement, denes a macro that replaces the name wherever it occurs in the e code. With no replacement, species a name 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.

Notes
A dene statement must be on a line by itself. The following is illegal:
define BIGMEM; import mod1.e;

The correct way to write the above is:


define BIGMEM; import mod1.e;

A dene statement only applies to e code that is loaded after the dene. The replacement must not contain the name. A statement like the following is illegal:
define bus_width top.bus_width; -- illegal

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.

Example 1
The following are name macro denitions:
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; Preliminary 17-3

e Language Reference Manual

Preprocessor Directives

#ifdef, #ifndef

Example 2
To use a dene macro, refer to the name. Given the denitions above, you could use them as in the following:
struct example { test_defines() is { var i: int; var j: int; print OFFSET, FIRST, SECOND; // Prints 5, 6, 7 i = 5; j = 6; print MULTIPLY_I_J + 3; // Prints 33 (5 * 6 + 3) #ifdef LG_CASE then { i = j * 2; print i; // Prints 12 (6 * 2) } #else { out("LG_CASE is not defined"); }; j = `bus_width * 2; print j; // Prints 128 (64 * 2) }; };

17.2 #ifdef, #ifndef


Purpose
Dene a preprocessor directive

Category
Statement, struct member, action, expression

Syntax
#if[n]def [`]name: macro-name then {text: string} [#else {text}] Syntax example:
17-4 Preliminary

e Language Reference Manual

#ifdef, #ifndef
#ifdef MEM_LG then { import mml.e; };

Preprocessor Directives

Parameters
name Without a backtick, a name dened in a dene statement. With a backtick (`name), a name dened with a Verilog `dene directive, or in a e dene statement where the macro is dened in Verilog style. text Code to be included based on whether the name macro has been dened.

For an #ifdef or #ifndef statement, only e statements can be used in text. For an #ifdef or #ifndef struct member, only struct members can be used
in text.

For an #ifdef or #ifndef action, only actions can be used in text.

Description
The #ifdef and #ifndef preprocessor directives are used together with dene name macros to cause the e parser to process particular code or ignore it, depending on whether a given name macro has been dened.

The #ifdef syntax checks whether the name macro has been dened and, if it has,
includes the code following then.

The #ifndef syntax checks whether the name macro has been dened 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 name macro has not been dened, the #else code is included. For #ifndef, if the name macro has been dened, the #else text is included.

Note
Except when it is within an #else block, the #ifdef or #ifndef keyword must be the rst keyword on the line.

Example 1
In this example, #ifdef is used as statements. The module named t_1.e contains the statement dene test_C. Neither test_A nor test_B is dened anywhere. Thus, only the t_4.e module is imported by the #ifdef statements.
e Language Reference Manual
Preliminary 17-5

Preprocessor Directives
<' 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; }; }; '>

#ifdef, #ifndef

Example 2
In this example, #ifdef is used as a struct member. The module contains the statement dene test_C. Neither test_A nor test_B is dened anywhere. Thus, only the keep t_data in [300..399] constraint is applied 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]; }; }; }; '>

See Also
Chapter 18, Importing e Files

17-6

Preliminary

e Language Reference Manual

18
See Also

Importing e Files

Imports (import statement, verilog import statement) load a given e le or Verilog le This chapter describes the import statement.

File Structure on page 2-2 verilog import on page 15-5

18.1 import
Purpose
Load other e modules

Category
Statement

Syntax
import le-name, | ( le-name, ) Syntax example:
e Language Reference Manual

Preliminary

18-1

Importing e Files
import test_drv.e;

import

Parameters
le-name, ... The names of les, separated by commas, that contain e modules to be imported. If no extension is given for a le name, an .e extension is assumed. The (le-name, ) syntax is for cyclic importing, in which one module references a eld in a second module, and the second module references a eld in the rst module. File names can contain references to environment variables using the UNIX notation $name or ${name}. Relative path indicators ./ and ../ can be used in lenames.

Description
Loads additional e modules before continuing to load the current le. If a specied module has already been loaded or compiled, the statement is ignored. 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 denition of struct A in module A, add an import of module B in which struct B is dened. 2. Before the denition 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 ( le-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 les 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.

18-2

Preliminary

e Language Reference Manual

import

Importing e Files

Notes
Within a given e module, import statements must appear before any other statements
except verilog import statements. (verilog import statements must always precede any other statements). Any other type of statement preceding an import statement is illegal.

Example 1
In the following example, a struct named pci_transaction is dened in one module, which is then imported into another module where additional elds and constraints are added in an extension to the struct denition.
<' // 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 2
In the following example, three modules are involved in cyclic referencing:

the switch.e module references the packet struct denition in the packet.e module the packet.e module references the cell struct denition in the cell.e module the cell.e module references the switch struct denition in the switch.e module.

e Language Reference Manual

Preliminary

18-3

Importing e Files

import

You only need to load the switch.e module. 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; }; > -----------------------------------------------------------< // 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 3
This example shows the explicit cyclic import syntax, import (le-name, ), using the same modules as Example 2 on page 18-3. 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.
< // 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; 18-4 Preliminary

e Language Reference Manual

import

Importing e Files
}; > -----------------------------------------------------------< // module packet.e - needs cell.e for the list of cell struct packet { !cells: list of cell; len: uint; }; > -----------------------------------------------------------< // module cell.e - needs switch.e for the switch definition struct cell { parent: switch; data[20]: list of byte; }; >

Example 4
This example shows how to load the les in Example 2 on page 18-3 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 dened 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 {

e Language Reference Manual

Preliminary

18-5

Importing e Files
!cells: list of cell; len: uint;

import

}; > -----------------------------------------------------------< // module cell.e - needs switch.e for the switch definition struct cell { data[20]: list of byte; }; >

See Also
#ifdef, #ifndef on page 17-4 verilog import on page 15-5

18-6

Preliminary

e Language Reference Manual

Index
Symbols
- subtraction operator syntax 2-43 - unary minus operator syntax 2-42 -- comment syntax 2-3 ! Boolean NOT operator syntax 2-36 != nonidentity operator syntax 2-46 !== Verilog nonidentity operator syntax 2-48 !~ string non-matching operator syntax 2-51 #ifdef statement syntax 17-4 #ifndef statement syntax 17-4 $0 string matching pseudo-variable 2-55 $1 - $27 string matching pseudo-variables 2-55 example 2-56 % modulo (remainder) operator syntax 2-43 %{ ... } bit concatenation operator syntax 2-64 & bitwise AND operator syntax 2-33 && Boolean AND operator syntax 2-37 (bits width) bit width specification syntax 3-28 (bits width-exp) size specification operator syntax 2-67 (byte width-exp) size specification operator syntax 2-67 (bytes width) byte width specification syntax 3-28 * multiplication operator syntax 2-43 * parameter passing by reference syntax 6-31 * unbounded integer syntax 3-4 + addition operator syntax 2-43 + unary plus operator syntax 2-42 . (period) at start of path name 2-27 . (period) field selection operator syntax 2-75 / division operator syntax 2-43 /.../ AWK regular expression syntax 2-54 // comment syntax 2-3 := assignment operator 7-2 < less than operator syntax 2-45 << bit shift left operator syntax 2-34 <= less than or equal to operator syntax 2-45 < begin code markers 2-2 = assignment action syntax 7-4 = assignment operator 7-2 == Boolean equality 7-5 == identity operator syntax 2-46 === Verilog identity operator 7-5 === Verilog identity operator syntax 2-48 => Boolean implication operator syntax 2-39 => Boolean imply operator syntax 2-39 > greater than operator syntax 2-45
Preliminary Index-1

e Language Reference Manual

Index

>= greater than or equal to operator syntax 2-45 >> bit shift right operator syntax 2-34 ? : conditional evaluation operator syntax 2-78 @ binary event temporal expression syntax 12-29 @ unary event temporal expression syntax 12-28 @n operator syntax 15-28 @sim event 11-5 emitting 12-6 simulator callback 11-10 @x operator syntax 15-28 @z operator syntax 15-28 [..] first match repeat syntax 12-22 [..] list slice operator syntax 2-61 [:] bit slice operator and packing 16-23 syntax 2-58 [;] temporal sequence syntax 12-17 [] in temporal expressions 12-17, 12-20, 12-22, 12-24 list index syntax 3-11 subscript operator 3-11 temporal repetition syntax 12-20 [name, ...] enumerated type definition syntax 3-24 [range, ...] range modifier operator syntax 2-66 [range, ...] scalar range syntax 3-27 \d regular expression digit 2-55 \D regular expression nondigit 2-55 \S regular expression non-white-space 2-55 \s regular expression white space 2-55 \W regular expression non-word 2-55 \w regular expression word 2-55 ^ bitwise XOR operator syntax 2-33 _ underscore in numbers 2-4

in names 2-8 { ; } list concatenation operator syntax 2-63 {} action block delimiters 2-13 | bitwise OR operator syntax 2-33 || Boolean OR operator syntax 2-38 ~ bitwise negation operator syntax 2-31 ~ string matching operator syntax 2-51 ~[..] true match repeat syntax 12-24 backtick in regular expressions 2-55 (apostrophe) syntax 2-77 (apostrophe) usage 2-77 (tick) field selection operator syntax 3-12 subtype selection syntax 3-7 > end code markers 2-2

Numerics
0c character symbol 2-7 2147483647 predefined constant 2-6 4-state. See four-state

A
abstract methods 4-20 declaring 6-15 restrictions on 6-17 actions = assignment 7-4 all of 13-7 assert 9-16 break 8-20 case bool-case-item 8-5 case labeled-case-item 8-3 check that 9-2 compute 6-25 conditional 8-1 continue 8-21 dut_error() 9-3 error() 9-11 executing 12-36

Index-2

Preliminary

e Language Reference Manual

Index

executing conditionally, overview 2-15 executing iteratively, overview 2-15 fatal() 9-13 first of 13-8 for 8-15 for each file matching 8-18 in loop 8-11 line in file 8-17 for from to 8-14 force 15-24 if then else 8-2 iterative 8-7 method() 6-23 op= assignment 7-6 overview 2-13 release 15-26 repeat until 8-10 return 6-27 start tcm() 6-21 sync 13-2 tcm() 6-19 try 9-14 var 7-2 wait 13-4 warning() 9-10 while 8-8 alias option, vhdl function statement 15-19 alias option, vhdl procedure statement 15-21 all of action syntax 13-7 also method extension option 6-9, 6-11 and in compound constraint Boolean expression 10-20 temporal expression syntax 12-14 apostrophe usage 2-77 See also , tick arithmetic operators 2-42 as_a type casting operator

subtype casting 3-11 ASCII characters 2-7 assert action syntax 9-16 assignment of Boolean types 3-18 compound (op=) 7-6 defined 3-16 of enumerated types 3-18 of lists 3-20 of numeric types 3-18 rules 3-16 simple (=) 7-4 of strings 3-20 of structs 3-19 assume 11-8 at_least coverage item option 14-8 at_least cross coverage item option 14-19 at_least transition coverage item option 14-24 attribute struct member syntax 4-22

B
b binary number symbol 2-5 backslash characters 2-7 behavioral rules specifying 4-4 temporal 11-6, 11-8, 12-9 binary integers 2-4 bit selects constraining 10-4 bit slices constraining 10-4 bit width, specifying 3-28 bits ANDing 2-33 concatenating 2-64 negating 2-31 ORing 2-33 shifting right, left 2-34 slicing 2-58
Preliminary Index-3

e Language Reference Manual

Index

XORing 2-33 Boolean data type. See bool types, assigning 3-18 Boolean FALSE 2-6 Boolean operators 2-36 Boolean TRUE 2-6 brackets. See [] break action syntax 8-20 byte width, specifying 3-28

C
C style loop 8-15 calling methods, without using value 6-25 carriage-return characters 2-7 case bool-case-item action syntax 8-5 case default option syntax 8-4 case labeled-case-item action syntax 8-3 case sensitivity in names 2-8 casting automatic 3-18, 3-22 reference parameters 3-23 signed integers to unsigned integers 3-23 change temporal expression syntax 12-33 characters escape sequences 2-6 in names 2-8 check effects setting with set_check() 9-8 check that action syntax 9-2 checking See also behavioral rules subtypes 2-71 code checking, action for 9-16 segments 2-2 comparison operators 2-45 values compared 2-47 compound
Index-4

constraint Boolean expressions 10-20 parameters, passing 6-31 restrictions on 6-32 compute action syntax 6-25 conditional actions 8-1 constants predefined 2-6 user-defined names 2-28 constraining numerics to even or odd 10-4 constraint Boolean expressions compound, and soft constraints 10-13 syntax 10-20 constraint-item expression syntax 10-23 constraints bit slice 10-4 and signed entities 10-5 and soft constraints 10-6 Boolean expressions 10-20 defined 10-1 defining 4-4, 10-1, 10-6 hard, defining 10-7 keep 10-7 keep for each 10-11 keep is_all_iterations() 10-9 keep reset_soft() 10-18 keep soft 10-13 keep soft select 10-15 on lists 10-2 nested 10-11 struct members 4-4 See also soft constraints constructs, overview 2-10 continue action syntax 8-21 cover is also struct member syntax 14-26 struct member syntax 14-1 coverage buckets defining 14-9 names 14-5, 14-6 covering bit slices 14-17

Preliminary

e Language Reference Manual

Index

covering list elements 14-16 covering predefined method expressions 14-16 cross items at_least option 14-19 defining 14-18 ignore option 14-19 illegal option 14-20 name option 14-19 options 14-19 weight option 14-20 when option 14-19 cross__item variable 14-20 effect of ranges on grading 14-11 grading default number of buckets 14-11 goals 14-8, 14-10, 14-19, 14-24 uint items 14-11 ungradeable values 14-11 groups defining 14-1 extending 14-26 global option 14-3 names 14-27 options 14-2 radix option 14-3 sampling events 14-2 struct members 4-4 text option 14-3 weight option 14-3 when option 14-3 hierarchical struct fields 14-16 holes 14-8, 14-10 false 14-10 items at_least option 14-8 at_least option example 14-13 at-least-num range option 14-10 cross 14-3 defining 14-2, 14-7, 14-27 every-count range option 14-9 ignore option 14-10

ignore option example 14-14 illegal option 14-10 illegal option example 14-15 name range option 14-9 names 14-8 no_collect option example 14-12 no_trace option example 14-16 options 14-8 radix option 14-11 radix option example 14-15 range option 14-9 ranges 14-5, 14-6 ranges option 14-9 ranges option example 14-13 text option 14-8 text option example 14-12 transition 14-3 types 14-8 weight option 14-11 weight option example 14-15 when option 14-8 when option example 14-13 See also coverage transition items, coverage cross items transition items at_least option 14-24 defining 14-23 ignore option 14-24 illegal option 14-24 name option 14-23 names 14-23 options 14-23 weight option 14-24 when option 14-24 transition__item variable 14-19, 14-25 coverage cross items defining 14-18 coverage groups defining 14-1 extending 14-26

e Language Reference Manual

Preliminary

Index-5

Index

coverage items defining 14-7 coverage transition items defining 14-23 cross coverage 14-18 item syntax 14-18 cross coverage item options 14-19 cross__item-name coverage syntax 14-20 cycle temporal expression syntax 12-31 cyclic import explicit 18-2 example 18-4 implicit 18-2 example 18-4

D
d decimal number symbol 2-5 data comparison 9-2 fields. See fields structs. See structs data types bit 3-3 bit concatenations 3-13 bool 3-3 byte 3-3 casting automatic 3-22 compound 3-6 enumerated, default value 3-6 for expressions 3-13 extending 3-24 HDL objects 3-13 int 3-3 lists 3-11 defaults 3-11 pack() expressions 3-13 precision 3-21 predefined scalar types 3-3 range modifiers 3-4 scalar defaults 3-3
Index-6

enumerated 3-5 named subtypes 3-4 sizes 3-3 subtypes 3-3 simulator objects 3-13 strings 3-13 defaults 3-13 structs 3-6 Boolean subtypes 3-7 subtypes 3-7 time 3-3 uint 3-3 unbounded integers 3-4 width modifiers 3-4 decimal integers 2-4 declarative_item option, vhdl function statement 15-19 declarative_item option, vhdl procedure statement 15-21 default sampling event 11-10 default, case action option 8-3, 8-5 define statement syntax 17-2 defines, Verilog importing 15-5 delay option, vhdl driver statement 15-15 detach temporal expression 12-8 disconnect_value option, vhdl driver statement 15-15 division rounding down 2-44 do option for each file matching loop 8-19 for each in loop 8-11 for each line in file loop 8-17 for from to loop 8-14 for loop 8-15 while loop 8-8, 8-10, 8-11 do_pack() predefined method 16-23 do_unpack() predefined method 16-23 documentation document conventions 1-2 documentation syntax notation 1-3

Preliminary

e Language Reference Manual

Index

dot at start of path name 2-27 down for from to option 8-14 drive option, verilog variable statement 15-10 drive_hold option, verilog variable statement 15-10 DUT errors defining responses 9-4 line in module, returning 9-5 method name, returning 9-5 struct name, returning 9-5 struct reference, returning 9-5 dut_error() action syntax 9-3 dut_error_struct predefined struct 9-4 dut_error_struct.check_effect() 9-5 dut_error_struct.message 9-5 dut_error_struct.pre_error() 9-6 dut_error_struct.set_check_effect() 9-6 dut_error_struct.source_location() 9-5 dut_error_struct.source_method_name() 9-5 dut_error_struct.source_struct() 9-5 dut_error_struct.source_struct_name() 9-5 dut_error_struct.write() 9-4, 9-6

E
e file names 2-8 .e files 2-2 e module names 2-8 e names legal 2-8 edges keep soft select option 10-16 else dut_error option, check that action 9-2 else error() option, assert action 9-16 else if option, if then else action 8-2 else option, if then else action 8-2 empty method declaration option 6-15 enumerated types assigning 3-18 numeric values 3-5 defining 3-24
e Language Reference Manual

empty 3-6 extending 3-6 names for values 2-23 renaming 3-5 scalars, extending 3-30 error detection and handling actions, overview 2-18 error handling programming errors 9-16 user errors 9-10 error() action syntax 9-11 errors exception handling 9-14 setting error message 9-11 setting warning message 9-10 event struct members defining 11-4 syntax 11-4 events @ binary syntax 12-29 unary syntax 12-28 @sim 11-5 binary sampling expression 12-29 checking for occurrences 2-40 invoking 11-3 is only redefinition 11-5 named 11-4 names 11-5, 11-6, 11-8 new_time 11-12 predefined 11-11 quit 11-12 redefining 11-5 sampling 11-9 scope of 11-3 session.start_of_test 11-11, 11-12 struct members 4-4 struct.quit 11-11 sys.any 11-10, 11-11, 11-12 sys.new_time 11-11 temporal expressions in 12-5 unary expression 12-28

Preliminary

Index-7

Index

unattached 11-5 in when subtypes 11-5 eventually temporal expression 11-12 syntax 12-19 exec temporal expression syntax 12-36 exists 12-37 expect struct member 4-4 syntax 11-6 temporal expressions in 12-5 expressions constraint Boolean expressions 10-20 data types of 3-13 HDL pathname 15-28 method() 6-23 operands 2-18 overview 2-18 tcm() 6-19 temporal 12-1 type checking 2-18 extend type statement syntax 3-30 extending coverage groups 14-26 enumerated scalar types 3-30 struct subtypes restrictions 4-8 structs, limitations with like 4-8

restricting values of 10-7 selecting . (period) operator 2-75 (tick) operator 3-12 soft constraints for, defining 10-13 struct members 4-4 type 4-13 ungenerated 4-13 unit instance fields 5-9 type fields 5-11 files importing 18-1 iteration actions 8-17 final_reorder 16-22 final_reorder field 16-22 first method extension option 6-9, 6-12 first of action syntax 13-8 flow control actions, overview 2-16 for action syntax 8-15 for each file matching action syntax 8-18 for each in action syntax 8-11 for each line in file action syntax 8-17 for from to action syntax 8-14 force action syntax 15-24 forcible option, verilog variable statement 15-10 fork and join using all of action 13-7, 13-9 using first of action 13-9 form-feed characters 2-7 four-state logic comparison operators 2-48 x value 2-48 z value 2-48

F
fail temporal expression syntax 12-12 fall temporal expression syntax 12-33 fatal() action syntax 9-13 fields defining 4-12 lists 4-15 of unit instances 5-13 of unit type 5-15 of structs, iterations of 10-10 path resolution 2-75 physical 4-13 packing 16-9 unpacking 16-9 referencing 2-20, 2-24, 2-25
Index-8

G
global coverage group option 14-3 global predefined struct 2-19 grading
e Language Reference Manual

Preliminary

Index

groups, weights 14-3 items, weights 14-11, 14-20, 14-24

H
h hexadecimal symbol 2-5 hard constraints defined 10-1 keep 10-7 keep for each 10-11 HDL objects accessing 15-28 forcing values on 15-24 releasing a force action 15-26 HDL pathname expression syntax 15-28 hexadecimal integers 2-4 holes. See coverage holes

I
if then else action syntax 8-2 ifdef. See #ifdef ifndef. See #ifndef ignore coverage item option 14-10 ignore cross coverage item option 14-19 ignore transition coverage item option 14-24 illegal coverage item option 14-10 illegal cross coverage item option 14-20 illegal transition coverage item option 14-24 implication operator in compound constraint Boolean expression 10-20 implicit packing and unpacking 16-24 implicit variables in constraint item definitions 10-23 in for each in loops 8-12 index 2-26 in lists 2-69 it 2-21, 2-24 in lists 2-69

me 2-21, 2-25 overview 2-24 imply operator in compound constraint Boolean expression 10-20 import avoiding module dependency example 18-5 import statement cyclic import 18-2 cyclic referencing 18-2 multiple modules 18-2 placement of 2-10, 18-3 syntax 18-1 importing Verilog macros 15-5 in range list operator syntax 2-52 in, constraining multiple lists 10-3 index implicit variable 2-26 index reference in constraint items 10-23 INERTIAL option, vhdl driver statement 15-16 inheritance like 4-2, 4-5 single 4-2 when 4-2, 4-4, 4-17 initial_value option, vhdl driver statement 15-16 inline method 6-10 restrictions on 6-4 inline method declaration option 6-2 inline only method extension option 6-9 instance names methods 2-22 pseudo-methods 2-22 routines 2-22 integer data type See int integers casting 3-23 maximum size 2-6 minimum size 2-6 See also numbers

e Language Reference Manual

Preliminary

Index-9

Index

interface option, vhdl function statement 15-18 interface option, vhdl procedure statement 15-21 is a Boolean operator syntax 2-71 is a struct subtype construct 10-21 is a subtype field reference 3-10 example 3-10 is a subtype syntax example 3-10 is also coverage group extension 14-26 is not a Boolean operator syntax 2-71 is only event syntax 11-5 is_a_permutation() and constraining lists 10-3, 10-8 it implicit variable 2-24 in constraint-item expression 10-23 item coverage item syntax 14-7 items defining constraints for 10-20 items in list, constraining 10-3 example of 10-8 iterative actions 8-7

L
library option, vhdl function statement 15-18 library option, vhdl procedure statement 15-21 like inheritance 4-5 language restrictions 4-2 limitations with extend 4-8 syntax 4-4 line in module, returning on DUT error 9-5 line option 8-17 list index operator syntax 2-56 list of <type> definition 3-11, 4-15 list of even integers constraining 10-4 list of list definition syntax 4-15 list of odd integers constraining 10-4 list of unit-type field definition syntax 5-15 list of unit-type is instance field definition syntax 5-13 list.list-method() pseudo-method calling syntax 2-69 list[size] definition 10-3 lists assigning 3-11, 3-20 concatenating 2-63 constraining 10-2 example of 10-8 defining 3-11, 4-15 fields 4-15 hash keys 3-12 indexes 3-11 initializing 10-3 keyed 3-12 of lists 3-11 multidimensional 3-11 multiple, constraining 10-3 packing and unpacking 16-10 passing to methods 6-31 restrictions on 6-32
e Language Reference Manual

K
K (kilo) multiplier 2-5 keep constraining list items 10-3 constraining list size 10-3 struct member syntax 10-7 keep for each constraining multiple list items 10-3 struct member syntax 10-11 keep is_all_iterations() constraining lists of structs 10-3 list method syntax 10-9 keep reset_soft() struct member syntax 10-18 keep soft struct member syntax 10-13 keep soft select struct member syntax 10-15 keywords, alphabetical list of 2-8
Index-10

Preliminary

Index

pseudo-methods invocation syntax 2-69 selecting items from 3-11 size constraining 10-3 initializing 10-3 of structs constraining 10-3 iterations of fields 10-10 unpacking data into 10-3 unpacking into scalar expressions 16-7 literal characters 2-7 loading multiple modules 18-2 loops 8-7 breaking execution of 8-20 continuing to next loop iteration 8-21 for (C-style) 8-15 for each file matching 8-18 for each in 8-11 for each line in file 8-17 for from to 8-14 overview 2-15 repeat until 8-10 while 8-8

M
M (mega) multiplier 2-5 macros names 17-2 substitution 17-2 MAX_INT 2-6 MAX_UINT 2-6 me implicit variable 2-25 in constraint-item expression 10-23 memory Verilog 15-12 method @event is struct member syntax 6-5 method [@event] is also|first|only|inline only struct member syntax 6-9

method [@event] is undefined|empty struct member syntax 6-15 method is inline struct member syntax 6-2 method is struct member syntax 6-2 method name, returning on DUT error 9-5 method() action or expression syntax 6-23 methods abstract 4-20, 6-15 restrictions on 6-17 declaring empty option 6-15 inline option 6-2 regular 6-2 undefined option 6-15 defined 6-1 extending also option 6-9, 6-11 first option 6-9, 6-12 inline only option 6-9 only option 6-9 invoking, overview 2-16 keep is_all_iterations() 10-9 parameters, maximum number allowed 6-4 passing parameters scalar 6-31 regular calling 6-23, 6-25 returning from 6-27 restrictions on 6-4 struct members 4-4 in struct subtypes 4-20 See also TCMs MIN_INT 2-6 mode option, vhdl driver statement 15-16 modules definition of 2-2 hierarchy 2-19 importing 18-1 loading 18-2 See also files multiple lists, constraining 10-3

e Language Reference Manual

Preliminary

Index-11

Index

example of 10-8

N
name cross coverage item option 14-19 name macros definition 17-2 with #ifdef, #ifndef 17-5 name resolution 2-26 name transition coverage item option 14-23 names resolving with path 2-27 without path 2-28 nesting constraints 10-11 nets releasing 15-26 new ... with struct allocation operator syntax 2-73 new struct allocation operator syntax 2-73 new-line character 2-6 now Boolean event check operator syntax 2-40 NULL value 2-6 numbers base representations 2-5 numeric data, assigning 3-18

(byte width-exp) size specification 2-67 . (period) field selection 2-75 = See = assignment action, op= assignment action ? conditional evaluation 2-78 @n 15-28 @x 15-28 @z 15-28 [ .. ] list slice 2-61 [ : ] bit slice 2-58 [] list index 2-56 [range, ...] range modifier 2-66 { ... } bit concatenation 2-64 { ; } list concatenation 2-63 is a 2-71 is not a 2-71 new struct allocation 2-73 or in compound constraint Boolean expression 10-20 temporal expression syntax 12-15 others keep soft select option 10-16

P
pack_options instances 16-13 struct 16-19 final_reorder 16-22 reverse_fields 16-19 reverse_list_items 16-20 scalar_reorder 16-21 package option, vhdl function statement 15-19 package option, vhdl procedure statement 15-21 packing advanced techniques for 16-12 basic techniques for 16-2 using bit concatenation 2-65 bit slice operator 16-23 customizing for struct 16-23
e Language Reference Manual

O
o octal number symbol 2-5 objects. See structs octal integers 2-4 on struct member 4-4 only method extension option 6-9 op= assignment action syntax 7-6 operator precedence non-temporal operators 2-29 operators (bits width-exp) size specification 2-67

Index-12

Preliminary

Index

defined 16-1 do_pack() 16-23 do_unpack() 16-23 implicit 16-24 lists 16-10 options customizing 16-19 packing.global_default 16-18 packing.high 16-15 packing.high_big_endian 16-16 packing.low 16-13 packing.low_big_endian 16-14 packing.network 16-17 order, default 16-3 pack_options struct 16-19 scalar expressions 16-6 simple example of 16-3 strings 16-8 structs 16-9 pack_options instances 16-13 and type conversion 16-1 packing.global_default 16-18 packing.high 16-15 packing.high_big_endian 16-16 packing.low 16-13 and implicit packing and unpacking 16-24 packing.low_big_endian 16-14 packing.network 16-17 parallel execution of action blocks 13-7, 13-8 parameters compound, passing 6-31 restrictions on 6-32 scalar, passing 6-31 pass keep soft select option 10-16 passing by reference 6-31 restrictions on 6-32 by value 6-31 pathnames. See paths paths

it implicit variable 2-21 paths to fields or structs 2-20 performance considerations and the inline option 6-3 physical fields packing 16-9 unpacking 16-9 predefined data types See data types predefined events 11-11 predefined methods instance names 2-22 predefined pack_options instances 16-13 predefined routines set_check() 9-8 predefined structs dut_error_struct 9-4 overview 2-19 preprocessor directives, defining 17-4 prev, in keep for each constraints 10-12 prev__item-name transition coverage item 14-24 programs, hierarchical structure of 2-19 pseudo-methods is_a_permutation() and constraining lists 10-3, 10-8 keep is_all_iterations() constraining lists of structs 10-3 list.list-method() invocation 2-69 reset_soft() 10-18

Q
quote characters 2-7

R
radix coverage group option 14-3 radix coverage item option 14-11 ranges coverage item option 14-9 specifying 2-66 reference parameters

e Language Reference Manual

Preliminary

Index-13

Index

casting 3-23 regular methods calling 6-23 without using value 6-25 declaring 6-2 abstract 6-15 defined 6-1 extending 6-9 passing parameters compound 6-31 restrictions on 6-32 scalar 6-31 restrictions for 6-4 returning from 6-27 See also methods release action syntax 15-26 repeat until action syntax 8-10 reserved words, alphabetical list of 2-8 result implicit variable 2-26 using to return a method 6-29 return action in extended methods 6-11 syntax 6-27 reusability, by extending structs 4-2 reverse option, for each in loop 8-11 reverse_fields 16-19 reverse_fields pack option 16-19 reverse_list_items 16-20 reverse_list_items pack option 16-20 rise temporal expression syntax 12-33

S
sampling events 11-9, 12-29 cycle expression 12-31 scalar expressions, packing and unpacking 16-6 parameters, passing 6-31 subtypes 2-66 defining 3-26 types specifying ranges for 3-26
Index-14

scalar modifiers 3-4 scalar_reorder 16-21 scalars enumerated, extending 3-30 sized, defining 3-28 specifying sizes 2-67 scope of events 11-3 selecting bits 2-58 semicolon temporal sequence operator 12-17 sequences, temporal 12-3, 12-8 session.start_of_test event 11-11, 11-12 set_check() predefined routine syntax 9-8 sign, changing 2-42 simulator callbacks 11-10 size of lists, constraining 10-3 sized integers defining 3-28 sized numbers 2-5 radix specification 2-5 width 2-5 soft not allowed in compound constraint Boolean expression 10-20 soft constraints and compound constraint Boolean expressions 10-13 defined 10-1 distribution of values, constraining 10-15 keep reset_soft() 10-18 keep soft 10-13 keep soft select 10-15 order of evaluation 10-2 start tcm() action syntax 6-21 statements #ifdef 17-4 #ifndef 17-4 define 17-2 extend type 3-30

Preliminary

e Language Reference Manual

Index

import 18-1 order of 2-10 overview 2-10 struct 4-3 type enumerated scalar 3-24 type scalar subtype 3-26 type sized scalar 3-28 unit 5-5 verilog code 15-2 verilog function 15-3 verilog import 15-5 verilog task 15-7 verilog time 15-9 verilog variable memory 15-12 verilog variable reg 15-10 verilog variable wire 15-10 vhdl code 15-13 vhdl function 15-17 vhdl procedure 15-20 vhdl time 15-23 step option for the for from to loop 8-14 strings accessing substrings 3-13 assigning 3-20 escape sequences in 2-6 matching 2-51, 2-54 AWK-style regular expressions 2-54 longest match 2-55 Perl-style regular expressions 2-55 shortest match 2-55 packing and unpacking 16-8 strobe option, verilog variable statement 15-10 struct members attribute 4-22 constraints 4-4 cover 14-1 cover is also 14-26 coverage groups 4-4 events 4-4, 11-4

expect 4-4, 11-6 fields 4-4, 4-12 keep 10-7 keep for each 10-11 keep reset_soft() 10-18 keep soft 10-13 keep soft select 10-15 lists 4-15 method @event is 6-5 method [@event] is also|first|only|inline only 6-9 method [@event] is undefined|empty 6-15 method is [inline] 6-2 methods 4-4 on 4-4 overview 2-12 types 4-4 when 4-4, 4-17 struct name, returning on DUT error 9-5 struct reference, returning on DUT error 9-5 struct statement syntax 4-3 struct.quit event 11-11, 11-12 structs allocating 2-73 assigning 3-19 creating 2-73 fields defining 4-12 restricting values for 10-7 hierarchy 2-19 lists of constraining 10-3 iterations of the fields 10-10 members. See struct members pack_options 16-19 packing and unpacking 16-9 passing to methods 6-31 restrictions on 6-32 referencing 2-20, 2-25 subtypes

e Language Reference Manual

Preliminary

Index-15

Index

creating 4-17 extending 4-10 like inheritance 4-5 method definition 4-20 when inheritance 4-4 subscripting lists 2-56 subtypes assigning 3-20 creating 4-17 definition 4-18 specifying 4-4 with tick 3-7 with when 3-9 See also struct subtypes sync action syntax 13-2 synchronizing TCMs 13-2, 13-5 syntactic elements, overview 2-10 syntax hierarchy 2-10 syntax notation for e constructs 1-3 sys predefined struct 2-19 sys, HDL path of 5-3 sys.any event 11-10, 11-11, 11-12 sys.new_time event 11-11 system variables ($0 to $27) 2-55

T
tab characters 2-7 tcm() action or expression syntax 6-19 TCMs calling 6-19 declaring 6-5 abstract 6-15 defined 6-7 extending 6-9 interrupting 13-2, 13-5 parallel actions 13-7, 13-8 parameters, maximum number of 6-7 passing parameters compound 6-31 restrictions on 6-32 scalar 6-31
Index-16

restrictions on 6-7 returning from 6-27 starting 6-21 synchronizing 13-2, 13-5 temporal behavioral rules 12-9 defining 11-6, 11-8 expressions => yield 12-27 @ binary sampling event 12-29 @ unary event 12-28 [..] first match repeat 12-22 [;] (sequence) 12-17 [] (repetition) 12-20 ~[..] true match repeat 12-24 and 12-14 change 12-33 context of 12-2, 12-5 cycle 12-31 definition of 12-1 detach 12-8 evaluation of 12-2, 12-3 in event definitions 12-5 eventually 12-19 exec 12-36 in expect constructs 12-5, 12-7 fail 12-12 failure of 12-3 fall 12-33 or 12-15 rise 12-33 sample forms 12-8 sampling events 11-9, 12-2 sequences 12-3 success of 12-3 in sync actions 12-7 transition 12-33 true 12-32 in Verilog objects 12-6 in wait actions 12-7 first match expression 12-22 operators 12-11

Preliminary

e Language Reference Manual

Index

precedence of 12-11 sequences 12-8 struct members expect 11-6 true match expression 12-24 yield operator 12-8 expressions in events 11-5 text coverage group option 14-3 coverage item option 14-8 then option for if then else action 8-2 tick field 3-12 subtype 3-7 time precision 15-9 units Verilog 15-9 VHDL 15-23 time scale, setting 15-9 time scale, setting for VHDL 15-23 time-consuming actions, overview 2-17 time-consuming methods See also TCMs timing behavior 12-2 transition coverage prev__item variable 14-24 transition coverage item options 14-23 transition coverage item syntax 14-23 transition temporal expression 12-33 transition__item-name coverage syntax 14-19, 14-25 transitions coverage 14-23 TRANSPORT option, vhdl driver statement 15-16 tristate logic comparison operators 2-48 x value 2-48 z value 2-48 true temporal expression syntax 12-32

try action syntax 9-14 type casting automatic 3-22 type enumerated scalar statement syntax 3-24 type scalar subtype statement syntax 3-26 type sized scalar statement syntax 3-28

U
unbounded unsigned integers 3-5 UNDEF value 2-6 undefined method declaration option 6-15 unit instance tree, definition of 5-1 unit members verilog function 15-3 verilog task 15-7 verilog variable memory 15-12 verilog variable reg | wire 15-10 vhdl driver 15-15 vhdl function 15-17 vhdl procedure 15-20 unit members, types 5-6 unit statement syntax 5-5 units associating with HDL paths 5-3 basic concepts 5-1 limitations 5-4 unit-type field definition syntax 5-11 unit-type is instance field definition syntax 5-9 unlabeled case condition action 8-5 unpacking defined 16-1 implicit 16-24 lists 16-10 scalar expressions 16-6 simple example of 16-5 strings 16-8 structs 16-9 and type conversion 16-1 See also packing unsigned integer
Preliminary Index-17

e Language Reference Manual

Index

data type. See uint unsigned integers maximum size 2-6 unsized numbers 2-4 until option wait action 13-4 untyped expression effect of ~ operator on 2-32 untyped expressions 3-13 user-defined methods instance names 2-22 using index option 8-11 using keyword coverage group options 14-2 coverage item options 14-8

V
values distribution of constraining 10-15 values, restricting 10-7 var action syntax 7-2 variables defining 7-2 dynamic 7-2 initializing 7-2 names 7-2 overview 2-14 scope 7-3 types 7-2 Verilog defines importing 15-5 reading 15-5 code in stubs file 15-2 four-state identity operators 2-48 functions declaring 15-3 memories specifying 15-12 objects
Index-18

accessing 15-11 in temporal expressions 12-6 registers, specifying 15-10 tasks calling from e 15-8 declaring 15-7 text macros importing 15-5 time resolution 15-9 wires, specifying 15-10 verilog code statement syntax 15-2 verilog function statement syntax 15-3 verilog import statement syntax 15-5 Verilog simulator interfaces, setting up 15-1 verilog task statement syntax 15-7 Verilog time scale 15-9 verilog time statement syntax 15-9 Verilog timescale 15-9 verilog variable drive option 15-10 drive_hold option 15-10 forcible option 15-10 strobe option 15-10 verilog variable memory statement syntax 15-12 verilog variable reg statement syntax 15-10 verilog variable wire statement 15-10 VHDL code in stub file 15-13 functions declaring 15-17 procedures calls to 15-22 declaring 15-20 time resolution 15-23 vhdl code statement syntax 15-13 vhdl driver delay option 15-15 disconnect_value option 15-15 INERTIAL option 15-16

Preliminary

e Language Reference Manual

Index

initial_value option 15-16 mode option 15-16 TRANSPORT option 15-16 vhdl driver unit member syntax 15-15 vhdl function alias option 15-19 declarative_item option 15-19 interface option 15-18 library option 15-18 package option 15-19 vhdl function statement syntax 15-17 vhdl procedure alias option 15-21 declarative_item option 15-21 interface option 15-21 library option 15-21 package option 15-21 vhdl procedure statement syntax 15-20 VHDL signals driving continuously via resolution function 15-15 releasing a force action 15-26 VHDL simulator interface, setting up 15-13 vhdl time statement syntax 15-23

referring to conditional fields 3-10 struct member syntax 4-17 transition coverage item option 14-24 when subtypes referring to fields in 3-10 while action syntax 8-8 wires releasing 15-26 with syntax. See new

Y
yield operator 12-8 See also => yield temporal expression yield temporal expression syntax 12-27

W
wait action syntax 13-4 warning() action syntax 9-10 weight coverage group option 14-3 weight coverage item option 14-11 weight cross coverage item option 14-20 weight transition coverage item option 14-24 weights, in keep soft select 10-16 when coverage group option 14-3 coverage item option 14-8 coverage item option syntax 14-8 cross coverage item option 14-19 inheritance
e Language Reference Manual
Preliminary Index-19

Index

Index-20

Preliminary

e Language Reference Manual

Das könnte Ihnen auch gefallen