100% found this document useful (1 vote)
255 views119 pages

VR Ad Lib2.0

Uploaded by

pinakin4u
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
255 views119 pages

VR Ad Lib2.0

Uploaded by

pinakin4u
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 119

The Register and

Memory Package
Version 2.0
Legal Notice
Copyright © 2003-2005 Verisity Design, Inc. All rights reserved.

Trademarks
Verisity, the Verisity logo, eAnalyzer, eCelerator, eRM, Invisible Specman, LicenseE, Pure
IP, Specman, Specman Elite, SpeXsim, SpeXtreme, SureCov, SureLint, SureSolve, sVM,
Verification Advisor, Verification Alliance, Verification Vault, Verification Viewport,
Visualization Toolkit, vManager, vPlan, Xbench, Xchange, Xcite, XoC, Xpert, Xsim, and
Xtreme are either trademarks or registered trademarks of Verisity Design, Inc. in the
United States and/or other jurisdictions. All other trademarks are the exclusive property of
their respective owners.

Confidentiality Notice
Verisity confidential; do not distribute. The contents of this document constitute valuable
proprietary and confidential property of Verisity Design, Inc. 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 confidential information of Verisity or its licensors, and is supplied subject to, and may
be used only by Verisity’s 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 reader’s responsibility to determine the applicable
regulations and to comply with them.
Contents

1 The Register and Memory Package . . . . . . . . . . . . . . . . . . . . . . . . .1-1


1.1 Introduction to the Register and memory package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-1
1.1.1 Main Features of the Register and Memory Package . . . . . . . . . . . . . . . . . . . 1-2
1.1.2 Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-2
1.1.3 Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-2
1.2 Overview of the Register and Memory Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-3
1.3 Architecture of the Register Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7
1.3.1 Defining the Register Address and Data Width . . . . . . . . . . . . . . . . . . . . . . . . 1-8
1.3.2 Defining a Register File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-9
1.3.3 Defining Registers with the reg_def Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-9
1.3.3.2 Defining a Register Instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-11
1.3.3.3 Defining Multiple Instances of a Register Type . . . . . . . . . . . . . . . 1-12
1.3.3.5 Mirroring Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-13
1.3.3.6 Defining Coverage of Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-14
1.3.4 Instantiating the Register File in the Architecture . . . . . . . . . . . . . . . . . . . . . 1-14
1.3.5 Instantiating the Address Map and the RSD . . . . . . . . . . . . . . . . . . . . . . . . . 1-15
1.3.6 Adding the Register File to the Address Map . . . . . . . . . . . . . . . . . . . . . . . . 1-15
1.3.6.1 Mirroring Register Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-16
1.4 Integration of the Register Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-16
1.4.1 Integrating the RSD with the BFM Sequence Driver . . . . . . . . . . . . . . . . . . 1-18
1.4.2 Updating the Register Model Using an eVC Monitor . . . . . . . . . . . . . . . . . . 1-20
1.5 Creating Register Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-20
1.5.1 Basic Register Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-21
1.5.3 Creating Deterministic Configuration Sequences . . . . . . . . . . . . . . . . . . . . . 1-25
1.5.4 Modifying a Register Field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-26
1.5.5 Writing to a Specific Instance of a Register Type . . . . . . . . . . . . . . . . . . . . . 1-26
1.5.6 Accessing Random Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-28

Register and Memory Package Version 2.0 iii


Contents

1.5.6.1 Accessing a Random Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-28


1.5.6.2 Accessing Entire Register Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-30
1.6 Using the Register Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-31
1.6.1 Implementing Side Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-32
1.6.2 Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-33
1.6.3 Coverage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-33
1.6.3.1 Coverage of Register Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-34
1.6.3.2 Adding or Modifying Coverage Definitions . . . . . . . . . . . . . . . . . . 1-35
1.6.3.3 Customizing Coverage Sampling . . . . . . . . . . . . . . . . . . . . . . . . . . 1-36
1.6.4 Backdoor Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-36
1.6.4.1 Enabling Backdoor Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-36
1.6.4.2 Backdoor Accessing of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . 1-37
1.6.4.3 Overriding the Default Backdoor Implementation . . . . . . . . . . . . . 1-38
1.6.4.4 Backdoor Accesses and Update of the Address Map . . . . . . . . . . . 1-39
1.6.5 Indirect Addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-39
1.6.5.1 Driving Indirect Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-40
1.6.5.2 Identifying and Handling Indirect Access . . . . . . . . . . . . . . . . . . . . 1-42
1.6.6 Changing the Register Field Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-43
1.6.7 Customizing Addressing Width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-44
1.6.8 Register Sequences and End of Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-45
1.6.9 Controlling Message Verbosity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-45
1.6.10 Accessing Multiple Address Maps on the Bus . . . . . . . . . . . . . . . . . . . . . . . . 1-46
1.6.11 Disabling Comparison for Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-47
1.7 Sparse Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-48
1.7.1 Instantiating a Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-48
1.7.2 Accessing Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-49
1.7.3 Updating the Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-50
1.7.4 Memory Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-51
1.7.4.1 Reading from and Writing to a File . . . . . . . . . . . . . . . . . . . . . . . . . 1-51
1.7.4.2 Controlling Returned Data of Uninitialized Addresses . . . . . . . . . . 1-52
1.7.4.3 Side Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-53
1.7.4.4 Memory Backdoor Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-53
1.7.5 Storing Complex Structures in Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-54
1.7.5.1 Creating Memory Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-55
1.7.5.2 Connecting Memory Objects to the Memory . . . . . . . . . . . . . . . . . 1-55
1.7.6 Accessing Objects in Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-57
1.7.6.2 Methods for Accessing Objects in Memory . . . . . . . . . . . . . . . . . . 1-58
1.8 Register and Memory Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-59
1.8.1 Type Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-59
1.8.2 Type Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-60

iv Version 2.0 Register and Memory Package


Contents

1.8.3Register Attribute Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-60


1.8.4vr_ad_operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-61
1.8.5vr_ad_reg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-61
1.8.5.14 Fields and Methods of vr_ad_reg . . . . . . . . . . . . . . . . . . . . . . . . . . 1-71
1.8.6 vr_ad_reg_static_info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-73
1.8.7 vr_ad_reg_file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-74
1.8.7.2 Fields and Methods of vr_ad_reg_file . . . . . . . . . . . . . . . . . . . . . . . 1-76
1.8.8 vr_ad_map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-78
1.8.8.7 Fields and Methods of vr_ad_map . . . . . . . . . . . . . . . . . . . . . . . . . . 1-84
1.8.9 vr_ad_mem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-86
1.8.10 vr_ad_sequence_driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-90
1.8.10.1 Fields and Methods of vr_ad_sequence_driver . . . . . . . . . . . . . . . . 1-90
1.9 Address Management (Sets) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-91
1.9.6 Memory-Management Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-97
1.10 Registers Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-98
1.10.1 All Address Maps Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-99
1.10.2 Top-Level Address Map Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-99
1.10.3 Detailed Address Map Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-100
1.10.4 Register Files Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-101
1.10.5 Address Sets Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-102
1.10.6 Register File Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-102
1.10.7 Stripe Chart Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-103
1.11 Register and Memory Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-104

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Index-1

Register and Memory Package Version 2.0 v


List of Figures

Figure 1-1 Registers in the ex_c_bus Environment . . . . . . . . . . . . . . . . . . . . . . . . 1-3


Figure 1-2 Address Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-4
Figure 1-3 Registers in the eRM Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7
Figure 1-1 Integrating the Register Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-17
Figure 1-2 Indirect Addressing Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-39
Figure 1-1 Register Data Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-61
Figure 1-1 Register File Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-74
Figure 1-1 Address Management Model Example . . . . . . . . . . . . . . . . . . . . . . . . 1-91
Figure 1-2 All Maps Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-99
Figure 1-3 Top-Level Address Map Page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-100
Figure 1-4 Address Map Page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-101
Figure 1-5 Register Files Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-101
Figure 1-6 Address Sets Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-102
Figure 1-7 Register File Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-103
Figure 1-8 Stripe Chart Page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-104

Register and Memory Package Version 2.0 vi


List of Tables

Table 1-1 Information Available from the operation Parameter. . . . . . . . . . . . . 1-18


Table 1-2 Fields of vr_ad_operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-22
Table 1-3 Fields of vr_ad_sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-23
Table 1-4 SIMPLE vr_ad_sequence Fields. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-28
Table 1-5 ALL_REGS_IN_FILE vr_ad_sequence Fields . . . . . . . . . . . . . . . . . 1-30
Table 1-6 Fields of INDIRECT vr_ad_sequence . . . . . . . . . . . . . . . . . . . . . . . . 1-41
Table 1-7 vr_ad_mem Memory Object Allocation Methods . . . . . . . . . . . . . . . 1-56
Table 1-8 vr_ad_mem_obj Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-58
Table 1-9 Register and Memory Package Type Naming Conventions . . . . . . . . 1-59
Table 1-10 Register-Related Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-60
Table 1-11 Main Register Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-61
Table 1-12 vr_ad_reg Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-72
Table 1-13 vr_ad_reg Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-72
Table 1-14 vr_ad_reg_static_info Fields. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-73
Table 1-15 vr_ad_node Fields. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-75
Table 1-16 Main Register File Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-75
Table 1-17 vr_ad_reg_file Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-76
Table 1-18 vr_ad_reg_file Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-77
Table 1-19 Main Address Map Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-78
Table 1-20 vr_ad_map Register-Related Fields . . . . . . . . . . . . . . . . . . . . . . . . . . 1-84
Table 1-21 vr_ad_map Register-Related Methods . . . . . . . . . . . . . . . . . . . . . . . . 1-84
Table 1-22 Main Memory Operations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-86
Table 1-23 vr_ad_mem Fields. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-89

Register and Memory Package Version 2.0 vii


List of Tables

Table 1-24 vr_ad_mem Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-89


Table 1-25 vr_ad_sequence_driver Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-90
Table 1-26 vr_ad_sequence_driver Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-91
Table 1-27 Main Address Set Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-93
Table 1-28 vr_ad_map Memory-Management Methods. . . . . . . . . . . . . . . . . . . . 1-97
Table 1-29 vr_ad_set Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-98

viii Version 2.0 Register and Memory Package


1 The Register and Memory
Package
This chapter contains:

• Section 1.1, “Introduction to the Register and memory package,” on page 1-1
• Section 1.2, “Overview of the Register and Memory Package,” on page 1-3
• Section 1.3, “Architecture of the Register Model,” on page 1-7
• Section 1.4, “Integration of the Register Model,” on page 1-16
• Section 1.5, “Creating Register Sequences,” on page 1-20
• Section 1.6, “Using the Register Features,” on page 1-31
• Section 1.7, “Sparse Memory,” on page 1-48
• Section 1.8, “Register and Memory Data Structures,” on page 1-59
• Section 1.9, “Address Management (Sets),” on page 1-91
• Section 1.10, “Registers Visualization,” on page 1-98
• Section 1.11, “Register and Memory Commands,” on page 1-104

1.1 Introduction to the Register and memory


package
The register and memory package (vr_ad) models the behavior of memory and registers. It contains
some built-in mechanisms with predefined types for efficient modeling.

The package addresses three independent aspects: address management, register modeling, and memory
modeling.

Register and Memory Package Version 2.0 1-1


The Register and Memory Package
Main Features of the Register and Memory Package

This section contains:

• Section 1.1.1, “Main Features of the Register and Memory Package,” on page 1-2
• Section 1.1.2, “Naming Conventions,” on page 1-2
• Section 1.1.3, “Compilation,” on page 1-2

1.1.1 Main Features of the Register and Memory Package


The main features supported in this package are:

Modeling of registers, • Defining register types


register files, and memory • Creating a hierarchy of addressable items
maps • Defining coverage for registers
• Maintaining consistency of the register model
• Modeling of sparse memory

Accessing registers using • Using layering for protocol-independent access


sequences • Accessing specific registers
• Accessing random registers
• Modifying a register field
• Backdoor accessing
• Indirect accessing

Address management • Allocating/deallocating addresses for registers and register files

1.1.2 Naming Conventions


Registers are entities in the global name space. When a system is created out of multiple subsystems,
register names might collide. Therefore, Verisity recommends using a unique prefix for all addressable
items names, following the unique naming conventions of eRM.

1.1.3 Compilation
The register and memory package (vr_ad) includes some macro definitions. Therefore, if you want to
compile the package with user code that relies on the package, you must compile the package first and
then compile the user code on top of the package.

1-2 Version 2.0 Register and Memory Package


The Register and Memory Package
Overview of the Register and Memory Package

1.2 Overview of the Register and Memory Package


This section presents an overview of the register and memory package components and the integration
of the package with an existing environment. For this purpose, we use the simple ex_c_bus environment
(see Figure 1-1). More complex examples can be found in the remaining sections. The following
components are introduced in addition to the basic eRM elements (env, agents, sequence drivers):

• Register File — Represents DUT agent registers. It contains a list of consecutive registers.
• Address Map — Represents the address space. It maps the register files and the memory blocks (if
any) in the address space, and it contains references to them. In a very simple environment with only
one register file, an address map may seem redundant. Address maps gain importance in environments
with multiple register files.
• Register Sequence Driver (RSD) — A dedicated sequence driver for register operations. The
functionality of the RSD resembles that of a virtual sequence driver.

Figure 1-1 Registers in the ex_c_bus Environment

ex_c_bus env
RSD Register
Address File
Map

Active Master Passive Slave

SD

Mon BFM Monitor

Figure 1-2 shows the connection between the various elements of the register and memory package.

Register and Memory Package Version 2.0 1-3


The Register and Memory Package
Overview of the Register and Memory Package

Figure 1-2 Address Map

For a detailed description of the data structures, see Chapter 1 “The Register and Memory Package”.

To create and integrate the register model into your ex_c_bus environment:

1. Define a register file, and reset all registers.

For example, you could define a register file named XCORE with a size of 256 bytes and reset all
registers as follows:
extend vr_ad_reg_file_kind : [XCORE];
extend XCORE vr_ad_reg_file {
keep size == 256;
post_generate() is also {
reset();
};
};
For details on defining a register file, see “Defining a Register File” on page 1-9.

2. Define the registers using the reg_def macro.


For example, you could define the EX_REG_TX_DATA register and automatically add it at offset 0
of XCORE as follows:
// NAME REGFILE ADDR
reg_def EX_REG_TX_DATA XCORE 8’h00 {
// name : type : mask : reset value
reg_fld data : uint(bits:8) : RW : 0;
};
For details on defining registers, see “Defining Registers with the reg_def Macro” on page 1-9.

1-4 Version 2.0 Register and Memory Package


The Register and Memory Package
Overview of the Register and Memory Package

3. Instantiate the new register file under a unit in your environment.

For example, you could instantiate the XCORE register file under the ex_c_bus env as follows:
extend ex_c_bus_env {
reg_file : XCORE vr_ad_reg_file;
};
For details on where and how to instantiate the register file, see “Instantiating the Register File in the
Architecture” on page 1-14.

4. Instantiate an address map and a register sequence driver.

The register sequence driver must be linked to the address map and it must have a default BFM
sequence driver.
For example, you could use the ex_c_bus env to instantiate both the address map and the register
sequence driver. You could use the BFM sequence driver of masters[0] as the default driver for the
register sequence driver (RSD).
extend ex_c_bus_env {
addr_map : vr_ad_map;
rsd: vr_ad_sequence_driver is instance;
keep rsd.addr_map == value(addr_map);
keep rsd.default_bfm_sd == masters[0].driver;
};
For details on instantiating the address map and the RSD, see “Instantiating the Address Map and
the RSD” on page 1-15.

5. Allocate an address space for the register file by adding it to the address map at the desired offset.

For example, you could allocate addresses starting from 0x0 as follows:
extend ex_c_bus_env {
post_generate() is also {
addr_map.add_with_offset(0,reg_file);
};
};
For details on adding the register file to the address map, see “Adding the Register File to the
Address Map” on page 1-15.

6. Implement the eVC BFM sequence driver’s vr_ad_execute_op() method, which takes the contents
of the register operation and executes it.

This is necessary for layering the register sequences on top of the eVC. For example, your
implementation of vr_ad_execute_op might use the read() and write() sequence methods as
follows:
extend ex_c_bus_driver {

Register and Memory Package Version 2.0 1-5


The Register and Memory Package
Overview of the Register and Memory Package

vr_ad_execute_op(op_item : vr_ad_operation) : list of byte @clock is {


if op_item.direction == WRITE {
sequence.write(op_item.address, reg_op.get_data());
} else {
result = pack(packing.low,sequence.read(op_item.address));
};
};
For details on integrating the register sequence driver with an eVC agent, see “Integrating the RSD
with the BFM Sequence Driver” on page 1-18.

7. Bind the eVC monitor to the address map for updating the register model and collecting coverage.

For example, you could use the transfer_end event detected by the monitor. The update() method is
called for write operations. The compare_and_update() method is called for read operations.
extend vr_xbus_bus_monitor_u {
on transfer_end {
if transfer.read_write == WRITE {
get_enclosing_unit(vr_xbus_env_u).addr_map.update(
transfer.addr,pack(packing.low,transfer.data),{});
} else {
compute get_enclosing_unit(vr_xbus_env_u).\
addr_map.compare_and_update(transfer.addr,
pack(packing.low,transfer.data));
};
};
};
For details on updating the registers from a monitor, see “Updating the Register Model Using an eVC
Monitor” on page 1-20.

You can now create register sequences and access the registers using the write_reg and read_reg
macros. For example:
extend vr_ad_sequence_kind: [MY_SEQ];
extend MY_SEQ vr_ad_sequence {
!tx_data : EX_REG_TX_DATA vr_ad_reg;
body() @driver.clock is only {
write_reg tx_data;
read_reg tx_data;
};
};

For details on accessing the registers, see “write_reg and read_reg Macros” on page 1-23.

1-6 Version 2.0 Register and Memory Package


The Register and Memory Package
Architecture of the Register Model

1.3 Architecture of the Register Model


The next two sections use the Verisity XSoC environment (vr_xsoc) to demonstrate an integration of the
register model. The environment contains two instances of XCore, controlled from an XBus master by
writing to the XCore registers. As a result of the register operations, the XCore performs read or write
transactions on the XSerial port. Figure 1-3 shows the register and address management aspect layered
on top of the architecture, including the address map, register file, and register sequence driver.

Figure 1-3 Registers in the eRM Architecture

• Typically each XCore is represented by a module eVC. The best place to instantiate the register file
is in the module eVC. If your environment does not have a module eVC, you can instantiate the
register file in the XBus env or in the PASSIVE slave agent.
• The XBus passive slave has a reference to the register file instantiated in the module eVC.
• The XBus env has the address map and the register sequence driver (RSD).
• The RSD is layered on top of the BFM sequence driver.

To create the register model:

1. Define a register file.

2. Define the register types and optionally add instances of those registers into a register file (using the
reg_def macro).

Register and Memory Package Version 2.0 1-7


The Register and Memory Package
Defining the Register Address and Data Width

3. Instantiate the register file in the architecture (for example, in an agent) with no absolute address
assigned yet.

4. Instantiate the address map and the register sequence driver in the environment.

5. Add the register file to the address map (setting the absolute base address for the register file). This
can be done at runtime or at post-generate.

This section contains:

• Section 1.3.1, “Defining the Register Address and Data Width,” on page 1-8
• Section 1.3.2, “Defining a Register File,” on page 1-9
• Section 1.3.3, “Defining Registers with the reg_def Macro,” on page 1-9
• Section 1.3.4, “Instantiating the Register File in the Architecture,” on page 1-14
• Section 1.3.5, “Instantiating the Address Map and the RSD,” on page 1-15
• Section 1.3.6, “Adding the Register File to the Address Map,” on page 1-15

1.3.1 Defining the Register Address and Data Width


The address and data fields are unsigned integers with default size defined as follows:
define VR_AD_ADDRESS_WIDTH 32;
define VR_AD_DATA_WIDTH 32;

type vr_ad_addr_t: uint(bits:VR_AD_ADDRESS_WIDTH);


type vr_ad_data_t: uint(bits:VR_AD_DATA_WIDTH);

If your address or data width exceeds these default settings, you must change them to the highest value
to be used in your verification environment. As these statements define the actual types used in the
model, they must be set before the vr_ad package is loaded. For example, if your largest registers are 64
bits wide, you must define VR_AD_DATA_WIDTH to be 64, and your configuration file must start
with the following lines:
define VR_AD_DATA_WIDTH 64;
import vr_ad/e/vr_ad_top;

If your address space is a 64 bits wide, you must define VR_AD_ADDR_WIDTH to be 64, and your
configuration file must start with:
define VR_AD_ADDRESS_WIDTH 64;
import vr_ad/e/vr_ad_top;

1-8 Version 2.0 Register and Memory Package


The Register and Memory Package
Defining a Register File

1.3.2 Defining a Register File


To define a register file:
• Define the new kind of register file with its size, and reset all registers.
For example:
extend vr_ad_reg_file_kind : [XCORE];
extend XCORE vr_ad_reg_file {
keep size == 256;
post_generate() is also {
reset();
};
};
The size is in terms of how many addresses it occupies (and not the number of registers it contains).
This register file occupies 256 consecutive address entries when inserted into the memory map. By
default each address entry is a byte size, but you can change that. (See 1.3.6 “Adding the Register
File to the Address Map” and Appendix 1 “The Register and Memory Package”.)

1.3.3 Defining Registers with the reg_def Macro


The reg_def macro is provided for easy definition and instantiation of the registers. The macro defines
the register type and optionally instantiates it under a register file. If the register has a single instance in
the verification environment, provide the register file name and offset for this instance. If multiple
instances will be created, omit the register file name and offset and create the instances as described in
“Defining Multiple Instances of a Register Type” on page 1-12.

This section contains:

• Section 1.3.3.1, “reg_def Macro,” on page 1-10


• Section 1.3.3.2, “Defining a Register Instance,” on page 1-11
• Section 1.3.3.3, “Defining Multiple Instances of a Register Type,” on page 1-12
• Section 1.3.3.4, “reg_list Macro,” on page 1-13
• Section 1.3.3.5, “Mirroring Registers,” on page 1-13
• Section 1.3.3.6, “Defining Coverage of Fields,” on page 1-14

Register and Memory Package Version 2.0 1-9


The Register and Memory Package
Defining Registers with the reg_def Macro

1.3.3.1 reg_def Macro


This macro defines a register type with the write mask and reset value defined for each register field.

Syntax
reg_def reg-name [register-file-name offset] {
reg_fld field-name : field-type : field-mask : field-reset-value [: cov];…
};

Syntax example:
reg_def EX_REGS_TX_MODE XCORE 0x100 {
reg_fld dest : uint(bits:2) : RW : 0x0 : cov;
reg_fld frame_kind : [DATA,MESSAGE,A,B](bits:2) : RW : DATA : cov;
};

Parameters

reg_name Register name — Must follow eRM naming conventions and use a
company prefix

register-file-name (Optional) Name of the register file where the register is instantiated

offset (Optional) Offset of the register in the register file

field-name Register field name

field-type Register field type

field-mask Field mask — Can be R (Read Only), W (Write Only) or RW


(Read/Write)

field-reset-value Field value to be set on reset

cov (Optional) Add coverage for the field

Notes
• The keyword reg_fld automatically defines the register field as a physical field (%).
• The reset value must be a legal value for the type of the declared field. For example, if the field is
defined as Boolean, the reset value must be either TRUE or FALSE. Fields that are structs or lists
should get a number for the entire field.
• You can specify only the field name and type. In that case, the default mask is RW, and the reset value
is 0.

1-10 Version 2.0 Register and Memory Package


The Register and Memory Package
Defining Registers with the reg_def Macro

1.3.3.2 Defining a Register Instance


To define a register instance:
• Use the reg_def macro.

Example
You could create an “EX_REGS_TX_MODE” register with several fields and instantiate a copy of it
under the XCORE register file as follows:
// NAME FILE OFFSET
reg_def EX_REGS_TX_MODE XCORE 8’h03 {
// Custom Fields
reg_fld dest : uint(bits:2) : RW : 0 : cov;
reg_fld frame_kind : [DATA,MESSAGE,A,B](bits:2) : RW : DATA : cov;
reg_fld resv : uint(bits:4) : RW : 0 ;
};

The above code is translated by the macro into:


extend vr_ad_reg_kind : [EX_REGS_TX_MODE];
extend EX_REGS_TX_MODE vr_ad_reg {
%dest : uint(bits:2);
%frame_kind : [DATA,MESSAGE,A,B](bits:2);
%resv : uint(bits:4);
cover reg_access (kind == EX_REGS_TX_MODE) is also {
item ex_reg_tx_mode_dest = dest;
item ex_regs_tx_mode_frame_kind = frame kind;
};
update_attributes() is also {
// This method is called automatically. It contains internal code
// to store the static parameters in the static_info struct
};
};

extend XCORE vr_ad_reg_file {


%ex_regs_tx_mode : EX_REGS_TX_MODE vr_ad_reg;
post_generate() is also {
add_with_offset(8'h3,ex_regs_tx_mode);
};
};

The default field order of a register is from high bit position to low bit position. For example, the field
order of the EX_REGS_TX_MODE register is:
extend EX_REGS_TX_MODE vr_ad_reg {
%dest : uint(bits:2); // Bits [7:6]

Register and Memory Package Version 2.0 1-11


The Register and Memory Package
Defining Registers with the reg_def Macro

%frame_kind : [DATA,MESSAGE,A,B](bits:2); // Bits [5:4]


%resv : uint(bits:4); // Bits [3:0]
};

For instructions on changing the default field order, see “Changing the Register Field Order” on page
1-43.

Note The name of the register that is automatically added to the register file is the register kind
in lower case. So, with the above example, you can directly access the register
xcore_reg_file.ex_regs_tx_mode.

See Also
• “Fields and Methods of vr_ad_reg” on page 1-71

1.3.3.3 Defining Multiple Instances of a Register Type


To define multiple instances of a register type:

1. Create the register type using the reg_def macro, but do not specify a register file name or offset.

For example:
// NAME
reg_def EX_REGS_PORT_CONTROL {
reg_fld control : port_control_kind_t;
};

2. Extend the register file to add instances of the register type using the add_with_offset() method.

For example:
extend vr_ad_reg_file_kind : [PORTS];
extend PORTS vr_ad_reg_file {
port_regs[4] : list of EX_REGS_PORT_CONTROL vr_ad_reg;
post_generate() is also {
for each (p) in port_regs {
add_with_offset(index*4, p);
};
};
};
Note You can also use the reg_list macro here (see “reg_list Macro” on page 1-13).

1-12 Version 2.0 Register and Memory Package


The Register and Memory Package
Defining Registers with the reg_def Macro

1.3.3.4 reg_list Macro


This macro instantiates a register list inside a register file and automatically calls add_with_offset() for
each register in the register list. The registers are not generated but rather created by a new action (for
performance reasons). Verisity recommends using this macro when you must generate a large list of
registers.

Syntax
reg_list list-name[list-size] of reg-kind at offset;

Syntax example:
extend EX_FILE vr_ad_reg_file {
reg_list regs[128] of EX_REG at 0x1000;
};

Parameters

list-name Name of the created list field

list-size Size of the created list

reg-kind Kind of registers in the list

offset Starting address from which the registers are subsequently added

1.3.3.5 Mirroring Registers


Occasionally, a register is mapped in multiple locations in the register file. In such cases, the register can
be accessed via multiple addresses.

To implement mirroring of registers:


• Use the add_with_offset() method.
For example, you could define EX_REG_TX_MODE register at address 0x3 of the XCORE
register file and mirror the register at address 0x10 as follows:
// NAME FILE OFFSET
reg_def EX_REGS_TX_MODE XCORE 8’h03 {
// Custom Fields
reg_fld dest : uint(bits:2) : RW : 0 : cov;
reg_fld frame_kind : [DATA,MESSAGE,A,B](bits:2) : RW : A : cov;
reg_fld resv : uint(bits:4) : RW : 0 ;

Register and Memory Package Version 2.0 1-13


The Register and Memory Package
Instantiating the Register File in the Architecture

};
// Add Mirror address
extend XCORE vr_ad_reg_file {
post_generate() is also {
add_with_offset(0x10,ex_regs_tx_mode);
// Note: ex_regs_tx_mode is automatically defined by the
// "reg_def" macro as a field of the XCORE register file.
};
};

See Also
• add_with_offset() on page 1-75

1.3.3.6 Defining Coverage of Fields


Coverage per register field can be defined automatically by adding the attribute cov to the reg_fld
definition in the reg_def macro. This adds a coverage item of the field to the reg_access coverage group.

Example
The following code would be automatically created by the register definition in the example found in
“Mirroring Registers” on page 1-13.

extend EX_REGS_TX_MODE vr_ad_reg {


cover reg_access(kind == EX_REGS_TX_MODE) is also {
item ex_regs_tx_mode_dest;
item ex_regs_tx_mode_frame_kind;
};
};

See Also
• Chapter 1 “The Register and Memory Package”

1.3.4 Instantiating the Register File in the Architecture


The register file represents the DUT agent registers. Instantiate it in the module eVC or in the passive
agent of the interface eVC.

To instantiate the register file in a passive agent:


• Extend the relevant agent with the required instances.

1-14 Version 2.0 Register and Memory Package


The Register and Memory Package
Instantiating the Address Map and the RSD

For example:
extend PASSIVE SLAVE vr_xbus_agent_u {
reg_file : XCORE vr_ad_reg_file;
};

1.3.5 Instantiating the Address Map and the RSD


The address map represents the entire address space. It contains pointers to all register files in the
address space. It is used as a reference model. Instantiate it in the env corresponding to the address
space.

If you want to use register sequences, an RSD must also be instantiated at the same place and connected
to the address map. The RSD gets the information it requires for accessing registers from the address
map. The RSD should also be connected to a default BFM SD (for example, an xbus sequence driver) so
that it can perform the register operation according to the specific bus protocol.

To instantiate the address map and the RSD:


• Extend the relevant env with the required address map and RSD instances.
For example:
extend vr_xbus_env_u {
addr_map : vr_ad_map;
reg_driver: vr_ad_sequence_driver is instance;
keep reg_driver.addr_map == value(addr_map);
keep reg_driver.default_bfm_sd == active_masters[0].driver;
};

1.3.6 Adding the Register File to the Address Map


The vr_ad_map.add_with_offset() method allocates address space for the register file and adds it to the
address map. Typically this is done in the post_generate() phase, but it can also be done during
simulation.

To add the register file to the address map:


• Use the add_with_offset() with the desired offset and register file.
For example:
extend vr_xbus_env_u {
post_generate() is also {
var reg_file = passive_slaves[0].
as_a(DUT_XCORE_0 vr_xbus_agent_u).reg_file;
addr_map.add_with_offset(0,reg_file);

Register and Memory Package Version 2.0 1-15


The Register and Memory Package
Integration of the Register Model

};
};

See Also
• add_with_offset() on page 1-79

1.3.6.1 Mirroring Register Files


Occasionally, a register file is mapped in multiple locations in the address space. In such cases, the
register file can be accessed via multiple addresses.

To implement mirroring of register files:


• Use the add_with_offset() method to allocate another address space for the register file.
For example, you could define an XCORE register file for access via addresses 0x100 and 0x1000
as follows:
extend vr_xbus_env_u {
reg_file : XCORE vr_ad_reg_file;
post_generate() is also {
addr_map.add_with_offset(0x100,reg_file);
addr_map.add_with_offset(0x1000,reg_file);
};
};

See Also
• add_with_offset() on page 1-79

1.4 Integration of the Register Model


To integrate the register model into an existing environment:

1. Connect the eVC monitor to the address map of the register model.

The monitor identifies DUT activity. For WRITE transactions, it updates the register model via the
update() method. For READ transactions it checks the received data via the
compare_and_update() method.

2. Implement the vr_ad_execute_op() method for your eVC SD.

The vr_ad_execute_op() method lets you layer the RSD on top of the BFM SD.

1-16 Version 2.0 Register and Memory Package


The Register and Memory Package

Note This step is needed only when the register and memory package drives registers.

Figure 1-1 describes the typical flow of a register operation.

Figure 1-1 Integrating the Register Model

The register operation flow can be divided into two parts as follows:

Driving Registers
1. The RSD activates the appropriate BFM sequence driver by calling its vr_ad_execute_op() method.

2. The BFM sequence driver executes the operation using the associated BFM.

3. The registers in the DUT XCore1 are updated.

Monitoring
4. The monitor in the PASSIVE slave picks up transactions on the bus.

5. The monitor notifies the address map by calling the update() method.

6. The address map updates the registers in the register file.

Register and Memory Package Version 2.0 1-17


The Register and Memory Package
Integrating the RSD with the BFM Sequence Driver

This section contains:

• Section 1.4.1, “Integrating the RSD with the BFM Sequence Driver,” on page 1-18 (Steps 1-3)
• Section 1.4.2, “Updating the Register Model Using an eVC Monitor,” on page 1-20 (Steps 4-6)

1.4.1 Integrating the RSD with the BFM Sequence Driver


Register sequences are executed by the register sequence driver (RSD). When a do action is executed,
the RSD activates the destination BFM sequence driver by calling its vr_ad_execute_op() method and
forwarding the register operation to it. The vr_ad_execute_op() method must be implemented by the
eVC developer. It converts the protocol-independent operation into eVC-specific bus transactions.
vr_ad_execute_op(operation : vr_ad_operation) : list of byte @clock;

The information needed for creating eVC-specific register access is available through the operation
parameter. The returned value of the method is a list of byte, used only for READ operations.

Table 1-1 describes the information that is typically required from the operation parameter.

Table 1-1 Information Available from the operation Parameter

Field/Method Description

address Address of the target bus transaction

direction Direction of the target bus transaction

addr_space Address space identifier (required only if you use it in the register
sequences)

byte_enable Byte enable (required only if you use it in the register sequences)

get_data() Data of the operation in a numeric form

get_lob_data() Data of the operation in a list of byte form

get_num_of_bytes() Number of bytes in data

get_reg() Returns the register (only for REG operations)

Example 1
You could implement the vr_ad_execute_op() method for the Verisity XBus eVC as follows.
extend vr_xbus_master_seq_kind : [REG_SEQ]
extend vr_xbus_master_driver_u {
// This example uses a dedicated sequence instead of MAIN for executing

1-18 Version 2.0 Register and Memory Package


The Register and Memory Package
Integrating the RSD with the BFM Sequence Driver

// the register operation


reg_seq : REG_SEQ vr_xbus_master_seq;
keep reg_seq.driver == me;
vr_ad_execute_op(op: vr_ad_operation): list of byte @clock is {
if op.direction == WRITE {
reg_seq.write(op.get_num_of_bytes(),data_size_in_byte,
op.address, op.get_data())
} else {
result = pack(packing.low,
reg_seq.read(op.get_num_of_bytes(), op.address));
};
};
};

Note The above implementation uses the read and write methods of the native sequence. The
implementation of these methods is recommended by eRM. They are described in the section
on “Enhancing the User Interface” of the e Reuse Methodology (eRM) Developer Manual.

The read() and write() methods of the Verisity XBus eVC sequences are implemented as follows:
extend vr_xbus_master_sequence {
!trans: MASTER vr_xbus_trans_s;
// This method performs one write transfer on the bus.
write(size : uint, addr : uint(bits:16),
data : uint(bits:64)) @driver.clock is {
assert size in [1, 2, 4, 8];
do trans keeping {
.addr == addr;
.read_write == WRITE;
.size == size;
.data == pack(packing.low, data[size*8-1:0]);
};
};
// This method performs one read transfer on the bus.
read(size : uint, addr : uint(bits:16)) :
uint(bits:64) @driver.clock is {
assert size in [1, 2, 4, 8];
do trans keeping {
.addr == addr;
.read_write == READ;
.size == size };
if trans != NULL {
result = pack(packing.low, trans.data);
} else {
out("trans is NULL");
};
};

Register and Memory Package Version 2.0 1-19


The Register and Memory Package
Updating the Register Model Using an eVC Monitor

};

See Also
• Verisity XBus documentation

1.4.2 Updating the Register Model Using an eVC Monitor


Typically, the register model is updated by hooking it to a monitor. When the monitor identifies bus
activity, it interprets the activity and updates the register model using the update() method (for WRITE
transactions), and the fetch() or compare_and_update() methods (for READ transactions). The
compare_and_update() method compares the data from the bus with the data stored in the e model and
issues a DUT error for any mismatch. See also “Disabling Comparison for Registers” on page 1-47.

To implement automatic update of the model:


• Hook the model to the eVC monitor.
For example:
extend vr_xbus_bus_monitor_u {
on transfer_end {
if transfer.read_write == WRITE {
env.address_map.update(transfer.addr,%{transfer.data},{});
} else {
env.address_map.compare_and_update(
transfer.addr,%{transfer.data});
};
};
};

Notes
• Typically monitors contain an event (for example, transaction_end) that can be used for updating.
• Monitors should have access to a register file or address map. In the above example, access is achieved
through a reference to the address map in the env. If the register file is local to the agent enclosing
the monitor, the monitor can access it directly.

1.5 Creating Register Sequences


This section contains:

• Section 1.5.1, “Basic Register Operations,” on page 1-21


• Section 1.5.2, “write_reg and read_reg Macros,” on page 1-23

1-20 Version 2.0 Register and Memory Package


The Register and Memory Package
Basic Register Operations

• Section 1.5.3, “Creating Deterministic Configuration Sequences,” on page 1-25


• Section 1.5.4, “Modifying a Register Field,” on page 1-26
• Section 1.5.5, “Writing to a Specific Instance of a Register Type,” on page 1-26
• Section 1.5.6, “Accessing Random Registers,” on page 1-28

1.5.1 Basic Register Operations


The data item that represents a register access is vr_ad_operation. The vr_ad_operation struct carries
specific information about the actual operation to be performed on the register, such as the direction of
the operation, backdoor access, and so on. The same data item serves both register and memory
operations, implemented under different subtypes. The register-specific attributes are defined under the
REG subtype. The memory-specific attributes are defined under the MEM subtype.

The vr_ad_sequence is defined as a sequence of vr_ad_operation.

To perform a simple register access:


• Create a new subtype of vr_ad_sequence, and use the predefined op field as the sequence item.
For example, you could access the EX_REGS_TX_MODE register as follows:
extend vr_ad_sequence_kind : [MY_SEQ];
extend MY_SEQ vr_ad_sequence {
body() @driver.clock is only {
do op keeping {
.reg is a EX_REGS_TX_MODE vr_ad_reg;
.direction == WRITE;
};
};
};

As this syntax tends to get complicated when many constraints are needed or when indirect accessing is
required, Verisity recommends using the macros described in “write_reg and read_reg Macros” on page
1-23. The macros provide a more efficient implementation than the preceding example.

Table 1-2 and Table 1-3 list all controllable fields in vr_ad_operation and vr_ad_sequence. The rest of
this section provides more details on how and when to constrain these fields.

Register and Memory Package Version 2.0 1-21


The Register and Memory Package
Basic Register Operations

Table 1-2 Fields of vr_ad_operation

Field When Description

addr_space: vr_ad_space_kind Address space identifier. To be used if multiple


address spaces can be accessed from a single bus
(MEMORY / IO).The implementation of
vr_ad_execute_op() must take care of the
addr_space

address: vr_ad_addr_t Address used by the BFM sequence driver. It is filled


automatically by the register sequence driver, but it
can also be directly constrained

backdoor: bool TRUE for backdoor access. Default is FALSE. See


“Backdoor Operation” on page 1-36

byte_enable: vr_ad_data_t Can be used for specifying byte enables. vr_ad does
not use this value but just passes it on to the
vr_ad_execute_op() method. The implementation of
vr_ad_execute_op() must take care of the
byte_enable

dest_driver: Destination (BFM) sequence driver for this


any_sequence_driver operation. To be used if the destination is other than
the rsd.default_bfm_sd

direction: vr_ad_rw_t Operation direction — READ or WRITE

op_mode: vr_ad_op_mode Operation mode — REG or MEM

reg: vr_ad_reg REG The content of REG operation

static_item: vr_ad_base The addressable item instance to be accessed. To be


used if multiple registers of the same register kind
exist. See “Writing to a Specific Instance of a Register
Type” on page 1-26

1-22 Version 2.0 Register and Memory Package


The Register and Memory Package
Basic Register Operations

Table 1-3 Fields of vr_ad_sequence

Field When Description

addr_space: Address space identifier. To be used if multiple


vr_ad_space_kind address spaces can be accessed from a single bus
(MEMORY / IO). The implementation of
vr_ad_execute_op() must take care of the
addr_space

backdoor: bool TRUE for backdoor operations. See “Backdoor


Operation” on page 1-36

dest_driver: Destination (BFM) sequence driver for the sequence.


any_sequence_driver To be used if the destination is other than the
rsd.default_bfm_sd

indirect_seq: INDIRECT Predefined sequence for indirect access


vr_ad_sequence

mode: vr_ad_indirect_mode DIRECT or INDIRECT

op: REG vr_ad_operation Predefined sequence item for register accesses

prevent_test_done: bool TRUE to prevent the test from finishing as long as the
sequence is running

reg: vr_ad_reg INDIRECT Content of REG operation

static_item: vr_ad_base The addressable item instance to be accessed. To be


used if multiple registers of the same register kind
exist. See “Writing to a Specific Instance of a Register
Type” on page 1-26

Note Fields that appears both in vr_ad_operation and in vr_ad_sequence, by default, inherit
their values from their patent sequence.

1.5.2 write_reg and read_reg Macros


Two macros are provided for reading and writing registers.

Syntax
write_reg [{op-block-constraints}]
register-field [{register-block-constraints}]|[val[ue] register-value-exp]

Register and Memory Package Version 2.0 1-23


The Register and Memory Package
Basic Register Operations

read_reg [op-block-constraints] register-field

Parameters

op-block-constraints (Optional) Block of constraints for generating the operation


fields (vr_ad_operation)

register-field Register instance

register-block-constraints (Optional) Block of constraints for generating the register


fields

register-value-exp (Optional) Value to be written to the entire register

Usage

To use the write_reg and read_reg macros:


• Define a sequence field of the appropriate register type, and apply the relevant macro to it.
For example:
extend vr_ad_sequence_kind : [MY_SEQ];
extend MY_SEQ vr_ad_sequence {
!tx_mode : EX_REGS_TX_MODE vr_ad_reg;
body() @driver.clock is only {
write_reg tx_mode;
read_reg tx_mode;
};
};

To constrain the value of a specific field of a register:


• Add constraints in the register-block-constraints of the write_reg macro.
For example:
extend vr_ad_sequence_kind : [RWR];
extend RWR vr_ad_sequence {
!r1 : R1 vr_ad_reg;
body() @driver.clock is {
read_reg r1;
write_reg r1 {.field1 == 3};
read_reg r1;
};
};

1-24 Version 2.0 Register and Memory Package


The Register and Memory Package
Creating Deterministic Configuration Sequences

To assign a value for the entire register:


• Specify the value for the register in the write_reg value macro.
For example:
extend vr_ad_sequence_kind : [RWR];
extend RWR vr_ad_sequence {
!r1 : R1 vr_ad_reg;
body() @driver.clock is {
read_reg r1;
write_reg r1 value 0xaa;
read_reg r1;
};
};

For an example of using op-block-constraints, see “Writing to a Specific Instance of a Register Type” on
page 1-26.

1.5.3 Creating Deterministic Configuration Sequences


To create a deterministic configuration sequence:
• Use the relevant sequence of read or write register access.
For example, you could have a configuration sequence that sets the command and base address
registers of the PCI device and reads the status register after a short delay as follows.
extend vr_ad_sequence_kind: [VR_PCI_CONFIG];
extend VR_PCI_CONFIG vr_ad_sequence {
!command_reg : VR_PCI_COMMAND_REG vr_ad_reg;
!base_addr : VR_PCI_BASE_ADDR vr_ad_reg;
!status : VR_PCI_STATUS vr_ad_reg;
body() @driver.clock is only {
write_reg command_reg {
.io == FALSE;
.mem == TRUE;
.fast_back_to_back == FALSE
};
write_reg base_addr {
.offset == 0x10;
.mem_kind == MEM;
.base_addr == 0x30000
};
wait [10];
read_reg status;
if status.signalled_serr {

Register and Memory Package Version 2.0 1-25


The Register and Memory Package
Modifying a Register Field

out("signal_serr is enabled in ",status);


};
};
};

1.5.4 Modifying a Register Field


To modify a register field (doing read-modify-write using the value stored in the e model):

1. Locate the register by address or by kind with get_reg_by_address() or get_reg_by_kind().

2. Create a copy of the register using the copy() method and cast it to the exact register subtype.

3. Modify the copy of the register as desired.

4. Write the copy of the register back using the write_reg macro.

Example
extend MAIN vr_ad_sequence {
!xmode : EX_REGS_TX_MODE vr_ad_reg;
body() @driver.clock is only {
xmode = driver.addr_map.get_reg_by_kind(EX_REGS_TX_MODE).copy()\
.as_a(EX_REGS_TX_MODE vr_ad_reg);
xmode.dest = 2; // Modify field value
write_reg xmode {it == xmode}; // Write back the modified register.
};
};

1.5.5 Writing to a Specific Instance of a Register Type


Occasionally the same register type is used in several places. For example, a device with multiple ports
controlled by identical registers, one for each port, can be modeled using multiple instances of the same
register type. You might want to access a specific register, for example, the register of port number 2.

To write to a specific instance of a register type:


• Constrain vr_ad_operation.address to the right address or constrain vr_ad_operation.static_item to
the specific register instance (or the register file in which the register is unique).

1-26 Version 2.0 Register and Memory Package


The Register and Memory Package
Writing to a Specific Instance of a Register Type

Example 1
In the following example, there are two instances of the XCORE register file, located at address 0x100
and 0x200. The static_item field is constrained to a specific instance of the register file. Inside the
register file, the registers can be located uniquely by their type.
extend MAIN vr_ad_sequence {
!tx_data : EX_REGS_TX_DATA vr_ad_reg;
body() @driver.clock is only {
var reg_file1 : XCORE vr_ad_reg_file =
driver.addr_map.get_reg_file_by_address(0x100);
var reg_file2 : XCORE vr_ad_reg_file =
driver.addr_map.get_reg_file_by_address(0x200);
// Access tx_data of reg_file1
write_reg {.static_item == reg_file1} tx_data {.data == 0xaa};
// Access tx_data of reg_file2
write_reg {.static_item == reg_file2} tx_data {.data == 0xbb};
read_reg {.static_item == reg_file1} tx_data;
read_reg {.static_item == reg_file2} tx_data;
};
};

Example 2
In the following example, the register file contains a list of registers of the same type. The register type
is not unique inside the register file. Therefore, you must constrain the address of the operation to the
right register address. Alternatively, you can constrain the static_item field to the specific register
instance.
// Define EX_PORT_CTL register type.
reg_def EX_PORT_CTL {
reg_fld enable : bool;
reg_fld cmd : uint(bits:31);
};
// Add multiple instances of EX_PORT_CTL to the register file
extend PORTS vr_ad_reg_file {
port_regs[4] : list of EX_PORT_CTL vr_ad_reg;
post_generate() is also {
for each (p) in port_regs {
add_with_offset(index*4, p);
};
};
};
// Write to specific instances in the register list. When the PORTS
// register file is located at address 0x100, the first register in the
// register file is located at address 0x100, the second register is
// located at address 0x104...

Register and Memory Package Version 2.0 1-27


The Register and Memory Package
Accessing Random Registers

extend MAIN vr_ad_sequence {


port_reg : EX_PORT_CTL vr_ad_reg;
body() @driver.clock is only {
// Access register located at address 0x100
write_reg {.address == 0x100}
port_reg {.enable == TRUE;.cmd == 0xa };
// Access register located at address 0x104
write_reg {.address == 0x104}
port_reg {.enable == FALSE;.cmd == 0xb};
};
};

Note If more than one instance exists and no static_item or address is specified, an error
message is issued.

See Also
• “write_reg and read_reg Macros” on page 1-23
• add_with_offset() on page 1-75

1.5.6 Accessing Random Registers


This section contains:

• Section 1.5.6.1, “Accessing a Random Register,” on page 1-28


• Section 1.5.6.2, “Accessing Entire Register Files,” on page 1-30

1.5.6.1 Accessing a Random Register


Accessing a random register can be done using the predefined SIMPLE vr_ad_sequence. With the
SIMPLE sequence you can control the register kind and the data to be written. If you do not constrain
those fields, the kind of the register is generated as one of the register kinds that exist in the address map.
The data is generated randomly. If multiple registers of the same kind exist in the address map, the
SIMPLE sequence accesses one of them. Table 1-4 describes the controllable fields of SIMPLE
vr_ad_sequence.

Table 1-4 SIMPLE vr_ad_sequence Fields

Field Description

reg_kind : vr_ad_reg_kind Register kind

reg_addr : vr_ad_addr_t Register address (not to be used with reg_kind at the same time)

1-28 Version 2.0 Register and Memory Package


The Register and Memory Package
Accessing Random Registers

Table 1-4 SIMPLE vr_ad_sequence Fields

Field Description

reg_data : vr_ad_data_t Data to be written to the register

direction : vr_ad_rw_t READ or WRITE

To access a random register:


• Use the predefined SIMPLE sequence.

Example 1
Reading a random register out of the address map registers:
extend MAIN vr_ad_sequence {
!simple : SIMPLE vr_ad_sequence;
body() @driver.clock is only {
do simple keeping {
.direction == READ;
};
};
};

Example 2
Writing 0xaaaa to EX_REGS_TX_MODE register:
extend MAIN vr_ad_sequence {
!simple : SIMPLE vr_ad_sequence;
body() @driver.clock is only {
do simple keeping {
.reg_kind == EX_REGS_TX_MODE;
.direction == WRITE;
.reg_data == 0xaaaa;
};
};
};

Register and Memory Package Version 2.0 1-29


The Register and Memory Package
Accessing Random Registers

1.5.6.2 Accessing Entire Register Files


For accessing all registers in a register file, you must implement a dedicated sequence. An example of
such a sequence can be found in vr_ad/examples/vr_ad_reg_file_random_access.e. The test example
vr_ad_reg_file_random_access.e defines the ALL_REGS_IN_FILE sequence. The sequence accesses
all registers in the file in a specified order (ascending, descending, or random).

Table 1-5 ALL_REGS_IN_FILE vr_ad_sequence Fields

Field Description

reg_file_kind : vr_ad_reg_kind Register file kind

reg_file : vr_ad_addr_t Register file

order : vr_ad_data_t Order of accessing all registers in a register file. Can be


[ASCENDING, DESCENDING, RANDOM]

direction : vr_ad_rw_t READ or WRITE

Example
You could write an entire register file using the ALL_REGS_IN_FILE sequence as follows.

1. Generate an image of the file, optionally with constraints.


extend MAIN vr_ad_sequence {
!rgf_seq : ALL_REGS_IN_FILE vr_ad_sequence;
body() @driver.clock is {
// Generate a register file with constraint on several
// registers inside
var xcore : XCORE vr_ad_reg_file;
gen xcore keeping {
.vr_ad_tx_mode.dest == 1;
.vr_ad_tx_data.data == 0xaa;
};

2. Write the content of the file image to the DUT according to your preferred order.
// Write the register file in an ASCENDING order
do rgf_seq keeping {
.reg_file == xcore;
.order == ASCENDING;
.direction == WRITE
};
};
};

1-30 Version 2.0 Register and Memory Package


The Register and Memory Package
Using the Register Features

ALL_REGS_IN_FILE accesses each register in the register file. Following is a partial example of the
sequence body. For the full implementation, see the vr_ad_reg_file_random_access.e example.
extend ALL_REGS_IN_FILE vr_ad_sequence {
order : vr_ad_access_order;
direction : vr_ad_rw_t;
reg_file_kind : vr_ad_reg_file_kind;
keep soft reg_file_kind in
driver.addr_map.get_all_reg_files().kind;
reg_file : vr_ad_reg_file;
keep soft reg_file == NULL;
!all_reg_nodes : list of vr_ad_node;
body() @driver.clock is {
..............
if order == RANDOM {
// Gen a permutation of the registers
gen all_reg_nodes keeping {
it.is_a_permutation(reg_file.get_all_nodes());
};
} else if order == ASCENDING {
all_reg_nodes = reg_file.get_all_nodes();
} else {
all_reg_nodes = reg_file.get_all_nodes().reverse();
};
// Go over all registers
for each (node) in all_reg_nodes {
do op keeping {
.address == reg_file_offset + node.offset;
.reg == node.ad_item.as_a(vr_ad_reg);
.direction == direction;
};
};
};
};

1.6 Using the Register Features


This section contains:

• Section 1.6.1, “Implementing Side Effects,” on page 1-32


• Section 1.6.2, “Reset,” on page 1-33
• Section 1.6.3, “Coverage,” on page 1-33
• Section 1.6.4, “Backdoor Operation,” on page 1-36

Register and Memory Package Version 2.0 1-31


The Register and Memory Package
Implementing Side Effects

• Section 1.6.5, “Indirect Addressing,” on page 1-39


• Section 1.6.6, “Changing the Register Field Order,” on page 1-43
• Section 1.6.7, “Customizing Addressing Width,” on page 1-44
• Section 1.6.8, “Register Sequences and End of Test,” on page 1-45
• Section 1.6.9, “Controlling Message Verbosity,” on page 1-45
• Section 1.6.10, “Accessing Multiple Address Maps on the Bus,” on page 1-46
• Section 1.6.11, “Disabling Comparison for Registers,” on page 1-47

1.6.1 Implementing Side Effects


A post_access() hook is provided to implement side effects triggered by accessing a register. This hook
is activated only after completion of an update(), fetch(), or compare_and_update() operation;
however, it does provide access to the original value of the register before the operation and to the
parameters of the operation itself.

The post_access() hook method can be used for checking the legality of the register values. For
example, you could verify that a reserved field (resv) of EX_REGS_TX_MODE is always zero as
follows:
extend EX_REGS_TX_MODE vr_ad_reg {
post_access(direction : vr_ad_rw_t) is only {
check that resv == 0 else
dut_error("resv value must be 0 in ", me);
};
};

You can also use the post_access() hook to implement side effects such as “clear on read”:
extend EX_REGS_TX_MODE vr_ad_reg {
// Clear on Read
post_access(direction : vr_ad_rw_t) is {
if direction == READ {
write_reg_val(0x0);
};
};
};

The pre_access() hook method provides similar capabilities for actions needed just before the register is
accessed.

The static_info struct of the register contains information related to the last executed operation:

1-32 Version 2.0 Register and Memory Package


The Register and Memory Package
Reset

written_data Original data before masking


prev_value The value of the register before the operation
cur_value The current value of the register

For a full list of the fields of static_info, see vr_ad_reg_static_info on page 1-73.

These values can be used to update the corresponding value in the agent. For example you could update
the value of “cur_reg_value” in the agent based on the previous value and the value written into
EX_REGS_TX_MODE as follows:
extend EX_REGS_TX_MODE vr_ad_reg {
post_access(direction : vr_ad_rw_t) is only {
if static_info.written_data ==
0x1 and static_info.prev_value == 0x3 {
get_enclosing_unit(vr_abus_agent).cur_reg_value =
static_info.cur_value;
};
};
};

See Also
• “Fields and Methods of vr_ad_reg” on page 1-71
• write_reg_val() on page 1-62

1.6.2 Reset
Each register has a reset value specified in the reg_def macro. This value is restored automatically
whenever the reset() method is called for any register. Typically, reset() is called for register files or
address maps. In that case, the appropriate reset value is assigned to each contained register instance. For
example:
extend XCORE vr_ad_reg_file {
post_generate() is also {
reset();
};
};

1.6.3 Coverage
Coverage information is collected on each register access, that is, each time the update(), fetch(), or
compare_and_update() method is called.

Register and Memory Package Version 2.0 1-33


The Register and Memory Package
Coverage

The coverage group vr_ad_reg.reg_access is predefined in the package as follows:


cover reg_access is {
item kind using per_instance;
item direction : vr_ad_rw_t = static_info.direction;
cross kind, direction;
};

This section contains:

• Section 1.6.3.1, “Coverage of Register Fields,” on page 1-34


• Section 1.6.3.2, “Adding or Modifying Coverage Definitions,” on page 1-35
• Section 1.6.3.3, “Customizing Coverage Sampling,” on page 1-36

1.6.3.1 Coverage of Register Fields


To collect coverage for a specific register field:
• Add the attribute cov at the end of the reg_fld definition.
For example:
// NAME FILE OFFSET
reg_def EX_REGS_RX_MODE XCORE 32'h00000003 {
reg_fld dest : uint(bits:2) : RW : 0 : cov;
reg_fld frame_kind : uint(bits:2) : RW : 0 : cov;
reg_fld par_err : uint(bits:1) : RW : 0 ;
reg_fld valid_frame : uint(bits:1) : RW : 0 : cov;
reg_fld resv : uint(bits:2) : RW : 0 ;
};
Coverage information is collected only on the marked fields: dest, frame_kind, and valid_frame.
The following coverage group would be created for the preceding example. Each coverage item
name contains a prefix of the register kind to avoid name conflicts.
extend EX_REGS_RX_MODE vr_ad_reg {
cover reg_access(kind == EX_REGS_RX_MODE) is also {
item ex_regs_rx_mode_dest : uint(bits:2) = dest;
item ex_regs_rx_mode_frame_kind : uint(bits:2) = frame_kind;
item ex_regs_rx_mode_valid_frame : uint(bits:1) = valid_frame;
};
};

See Also
• “reg_def Macro” on page 1-10

1-34 Version 2.0 Register and Memory Package


The Register and Memory Package
Coverage

1.6.3.2 Adding or Modifying Coverage Definitions


To add cross coverage:
• Extend the specific instance of the coverage group.
For example:
extend EX_REGS_RX_MODE vr_ad_reg {
cover reg_access (kind == EX_REGS_RX_MODE) is also {
cross ex_regs_rx_mode_dest,ex_regs_rx_mode_frame_kind;
};
};

Sometimes you might want to ignore some of the predefined coverage values, for example, when a status
register can only be read and should never be written.

To ignore predefined coverage values:


• Extend the coverage definition with ignore.
For example:
extend vr_ad_reg {
cover reg_access is also {
item cross__kind__direction using also ignore=
kind == EX_REGS_TX_MODE and direction == READ or
kind == EX_REGS_RX_MODE and direction == WRITE;
};
};

To add ranges to an existing coverage item definition:


• Extend the definition of the coverage item under the appropriate per-instance subgroup with ranges.
For example:
extend VR_AD_TX_DATA vr_ad_reg {
cover reg_access(kind == VR_AD_TX_DATA) is also {
item vr_ad_tx_data_data using also ranges = {
range([0],"0");
range([1..254],"1..254");
range([255],"255");
};
};
};

Register and Memory Package Version 2.0 1-35


The Register and Memory Package
Backdoor Operation

1.6.3.3 Customizing Coverage Sampling


You might want to disable coverage sampling of a register file or to manually activate coverage sampling
of a specific register.

To disable coverage sampling of a register file:


• Constrain the has_coverage field of the register file to be FALSE.
For example:
extend my_agent {
xcore_file : XCORE vr_ad_reg_file;
keep xcore_file.has_coverage == FALSE;
};

To manually activate coverage sampling of a specific register:


• Emit the reg_access event of the appropriate register.
For example:
extend my_agent {
on interrupt {
status_reg.interrupt = TRUE;
emit status_reg.reg_access;
};
};

1.6.4 Backdoor Operation


This section contains:

• Section 1.6.4.1, “Enabling Backdoor Operation,” on page 1-36


• Section 1.6.4.2, “Backdoor Accessing of Registers,” on page 1-37
• Section 1.6.4.3, “Overriding the Default Backdoor Implementation,” on page 1-38
• Section 1.6.4.4, “Backdoor Accesses and Update of the Address Map,” on page 1-39

1.6.4.1 Enabling Backdoor Operation


Registers and memory can be accessed through a backdoor mechanism that relies on their HDL path.
The HDL path name is stored as a string in the backdoor_path field of the static_info. For registers that
have no backdoor, this field should remain empty.

1-36 Version 2.0 Register and Memory Package


The Register and Memory Package
Backdoor Operation

To enable backdoor operation:


• Set the backdoor_path to the correct HDL path.
For example:
reg_def R1 {
reg_fld data : uint(bits:32) : RW : 0;
set_static_info() is {
static_info.backdoor_path = "r1";
};
};

See Also
• vr_ad_reg_static_info on page 1-73

1.6.4.2 Backdoor Accessing of Registers


The backdoor field of the operation specifies whether the do is executed using the backdoor
mechanism. When the backdoor is set, the register sequence driver looks up the register in the reg_list
and uses the backdoor_path to access the register (using tick access).

If you constrain a sequence to run entirely in backdoor mode, there is no need to specify backdoor mode
for each do inside the sequence.

To access a register via a back door:


• Constrain the “backdoor” field of the relevant operation.
For example:
extend RWR vr_ad_sequence {
!r1 : R1 vr_ad_reg;
body() @driver.clock is {
read_reg {.backdoor == TRUE} r1;
write_reg {.backdoor == TRUE} r1 {.dest == 3};
};
};
If you prefer to use do op, you can achieve similar results as follows:
do op keeping {
.reg is a R1 vr_ad_reg (r1) and ...;
.backdoor == TRUE;
};

Register and Memory Package Version 2.0 1-37


The Register and Memory Package
Backdoor Operation

To constrain a sequence to run entirely in backdoor mode:


• Constrain vr_ad_sequence.backdoor to TRUE.
For example:
!rwr : RWR vr_ad_reg;
do rwr keeping {
.backdoor == TRUE;
};

See Also
• “write_reg and read_reg Macros” on page 1-23

1.6.4.3 Overriding the Default Backdoor Implementation


When the RSD executes a backdoor register operation at the lowest level, it calls the following
write_reg_val_backdoor() and read_reg_val_backdoor() hook methods. The default implementation
is as follows:
extend VR_AD_TX_MODE vr_ad_reg {
write_reg_val_backdoor(data : vr_ad_data_t) is only {
'(static_info.backdoor_path)' = data;
};

read_reg_val_backdoor() : vr_ad_data_t is only {


result = '(static_info.backdoor_path)'
};
};

You might require a non-standard implementation, for example, when your register has fields with a
different backdoor_path.

To override the default backdoor implementation:


• Extend the write_reg_val_backdoor() and read_reg_val_backdoor() hook methods.

See Also
• “Fields and Methods of vr_ad_reg” on page 1-71
• vr_ad_reg_static_info on page 1-73

1-38 Version 2.0 Register and Memory Package


The Register and Memory Package
Indirect Addressing

1.6.4.4 Backdoor Accesses and Update of the Address Map


Updating the address map is usually a monitor job, but monitors cannot recognize backdoor activities.
To keep the address map updated, each register backdoor sequence updates also the address map by
default. (Keep in mind that the address map might not be updated if a register was changed internally by
the DUT.) RSD has another flag that controls whether the result of a backdoor read access will be taken
directly from the address map instead of reading it from the DUT. This feature can be useful when you
want to check your register sequences but the DUT is not ready yet.

To change read access results to be taken directly from the address map:
• Constrain vr_ad_sequence_driver.bd_read_from_addr_map to be TRUE.
For example:
extend my_env {
rsd : vr_ad_sequence_driver;
keep rsd.bd_read_from_addr_map == TRUE;
};

1.6.5 Indirect Addressing


Some registers and register files are not mapped by the address map and can only be accessed indirectly.
In other words, reading and writing of unmapped registers is done through mapped registers. For
example, you could read from an unmapped register by writing the address into a mapped address
register and then reading the data from a data register.

Figure 1-2 Indirect Addressing Model

Register and Memory Package Version 2.0 1-39


The Register and Memory Package
Indirect Addressing

Unmapped registers must reside in an unmapped register file. If a register file is to be used for indirect
access:

• Do not assign an address to the unmapped register file (in other words, do not use
vr_ad_map.add_with_offset()).
• Add the unmapped register file to the addr_map.reg_file_list by calling
vr_ad_map.add_unmapped_item().

Support for indirect register accessing requires the following capabilities:

• Driving a register indirectly must be translated into a sequence of accesses to the corresponding
address and data registers (see Section 1.6.5.1, “Driving Indirect Registers,” on page 1-40).
• Any access to the data register must be passed to the unmapped register file (see Section 1.6.5.2,
“Identifying and Handling Indirect Access,” on page 1-42).

See Also
• vr_ad_map on page 1-78

1.6.5.1 Driving Indirect Registers


Accessing an unmapped register requires several accesses to mapped registers. Therefore, by default, the
write_reg and read_reg macros do not support access to unmapped registers. This section explains how
to enable unmapped registers for these macros.

Note Indirect access cannot be accomplished with the do operation. You must use the
write_reg macro.

To support indirect register accessing:

1. Implement a dedicated sequence of INDIRECT sequence mode to carry out all necessary operations
required for accessing the indirect register.

Note INDIRECT is another subtype and not the sequence name. The INDIRECT sequence
subtype contains several fields to be used in the sequence implementation. See “Fields of INDIRECT
vr_ad_sequence” on page 41.

2. Use set_indirect_seq_name() to inform the unmapped register file which sequence to execute upon
driving its registers.

Each time you access an unmapped register, the access is automatically translated to the appropriate
sequence of mapped register accesses.

1-40 Version 2.0 Register and Memory Package


The Register and Memory Package
Indirect Addressing

3. Add the unmapped register file to the address map using add_unmapped_item() (instead of
add_with_offset()).

This updates the address map with the unmapped registers.

Table 1-6 Fields of INDIRECT vr_ad_sequence

Field When Description

direction: vr_ad_rw_t INDIRECT Direction READ or WRITE

reg: vr_ad_reg INDIRECT Content of the unmapped register. For WRITE access, it
contains the data for the register access. For READ
access, you must update the register value

Unmapped registers have no absolute addresses but only offsets in the unmapped register file where they
reside. The vr_ad_reg.get_indirect_addr() method can be used to obtain the offset of the register in the
unmapped register file.

Example 1
This example contains an indirect sequence, ACTIVE_XCORE. It is extended with the subtype,
ACTIVE_XCORE INDIRECT.
extend vr_ad_sequence_kind : [ACTIVE_XCORE];
extend ACTIVE_XCORE INDIRECT vr_ad_sequence {
!ind_addr : EX_REGS_IND_ADDR vr_ad_reg;
!ind_data : EX_REGS_IND_DATA vr_ad_reg;
body() @driver.clock is only {
if direction == WRITE {
write_reg ind_data {.data == reg.read_reg_val()};
write_reg ind_addr {.addr==
reg.get_indirect_addr(driver.addr_map)};
} else {
write_reg ind_addr {.addr ==
reg.get_indirect_addr(driver.addr_map)};
read_reg ind_data;
// Update the returned register
reg.write_reg_val(ind_data.read_reg_val());
};
};
};

Register and Memory Package Version 2.0 1-41


The Register and Memory Package
Indirect Addressing

Example 2
This example shows how to use the vr_ad_reg_file.set_ indirect_seq_name() method to apply the
indirect register sequence (ACTIVE_XCORE) to the unmapped register file.
extend ex_c_bus_env {
indirect_reg_file : XCORE vr_ad_reg_file;
post_generate() is also {
indirect_reg_file.set_indirect_seq_name(ACTIVE_XCORE);
addr_map.add_unmapped_item(indirect_reg_file);
};
};

See Also
• “write_reg and read_reg Macros” on page 1-23
• vr_ad_reg_file on page 1-74

1.6.5.2 Identifying and Handling Indirect Access


To keep unmapped register files updated, each unmapped register file must be notified when any access
to the corresponding (mapped) data register occurs.

To facilitate automatic update of unmapped registers:

1. Connect the unmapped register file to the appropriate mapped register by calling vr_ad_reg.attach()
with the register file as a parameter.

The mapped register notifies the unmapped register file when any access occurs.

2. Implement the vr_ad_reg_file.indirect_access() method to define the behavior of the register file
upon notification.

Example 1
You could connect the unmapped register file to the mapped data register as follows.
extend ex_c_bus_env {
indirect_reg_file : XCORE vr_ad_reg_file
mapped_reg_file : MAP_REGS vr_ad_reg_file;
post_generate() is also {
// Set the unmapped reg file for notification
mapped_reg_file.ind_data.attach(indirect_reg_file);
};
};

1-42 Version 2.0 Register and Memory Package


The Register and Memory Package
Changing the Register Field Order

Example 2
You could implement notification handling for the unmapped register file via
vr_ad_reg_file.indirect_access() as follows.
extend XCORE vr_ad_reg_file {
!ind_addr : VR_AD_IND_ADDR vr_ad_reg; // Reference to the addr register
!ind_data : VR_AD_IND_DATA vr_ad_reg; // Reference to the data register
// indirect_access()
// On WRITE operation - update the relevant unmapped register.
// On READ operation - update the (mapped) VR_AD_IND_DATA register.
indirect_access( direction : vr_ad_rw_t, ad_item : vr_ad_base) is {
if ad_item is a VR_AD_IND_DATA vr_ad_reg {
if direction == WRITE {
// Update The unmapped register-file
update(ind_addr.addr,
pack(packing.high,ind_data.data), {});
} else { // READ
// Update the mapped data register with data from the
// unmapped reg-file
ind_data.data = fetch(ind_addr.addr,1)[:];
};
};
};
};

1.6.6 Changing the Register Field Order


The default field order of a register is packing.high, from a high bit position to a low bit position. The
first field declared in the register holds the highest bits and the last field declared in the register holds the
lowest bits. For example, the default field order of the EX_REGS_RX_MODE register is:
// NAME FILE OFFSET
reg_def EX_REGS_RX_MODE XCORE 32'h00000003 {
reg_fld dest : uint(bits:2); // Bits [7:6]
reg_fld frame_kind : uint(bits:2); // Bits [5:4]
reg_fld par_err : uint(bits:1); // Bits [3:3]
reg_fld valid_frame : uint(bits:1); // Bits [2:2]
reg_fld resv : uint(bits:2); // Bits [1:0]
};

Some specs use the opposite field order (packing.low). They interpret the same register definitions as:
// NAME FILE OFFSET
reg_def EX_REGS_RX_MODE XCORE 32'h00000003 {
reg_fld dest : uint(bits:2); // Bits [1:0]
reg_fld frame_kind : uint(bits:2); // Bits [3:2]

Register and Memory Package Version 2.0 1-43


The Register and Memory Package
Customizing Addressing Width

reg_fld par_err : uint(bits:1); // Bits [4:4]


reg_fld valid_frame : uint(bits:1); // Bits [5:5]
reg_fld resv : uint(bits:2); // Bits [7:6]
};

You can change the register packing option for a register file from packing.high to packing.low. The
change affects the packing option for all registers in the file. You cannot change the order for only some
of the registers in a register file.

To change the default packing option of a register file from packing.high to packing.low:
• Constrain vr_ad_reg_file.packing_mode to packing.low.
For example:
extend YCORE vr_ad_reg_file {
keep packing_mode == packing.low;
};

See Also
• vr_ad_reg_file on page 1-74

1.6.7 Customizing Addressing Width


The default addressing width for a register file is BYTE, which means every address entry contains one
byte only. Typically, memories are presented by address (offset) entries, where each line contains 4 bytes
and the offset jumps by 4 as follows:

byte4 byte3 byte2 byte1 0x0

byte8 byte7 byte6 byte5 0x4

byte12 byte11 byte10 byte9 0x8

Sometimes the required address width is Halfword or Word. In that case, each address entry will contain
two or four bytes instead of one byte as follows:

halfword2 halfword1 0x0

halfword4 halfword3 0x2

halfword6 halfword5 0x4

1-44 Version 2.0 Register and Memory Package


The Register and Memory Package
Register Sequences and End of Test

word1 0x0

word2 0x1

word3 0x2

To define a register file with a different addressing width:


• Constrain the field addressing_width_in_bytes of the register file.
For example, you could define a register file with HALFWORD width as follows:
extend vr_ad_reg_file_kind : [MY_HALFWORD_WIDTH];

extend MY_HALFWORD_WIDTH vr_ad_reg_file {


keep addressing_width_in_bytes == 2;
};

1.6.8 Register Sequences and End of Test


Register sequences contain a flag that controls whether the sequence will have an objection to end of test
and will automatically raise and drop an objection to TEST_DONE. By default this flag is turned off. In
other words, by default, register sequences do not influence the end of test decision.

To involve register sequences in the end of test decision:


• Constrain vr_ad_sequence.prevent_test_done to TRUE.
extend MAIN vr_ad_sequence {
keep prevent_test_done == TRUE;
};

See Also
• “Basic Register Operations” on page 1-21

1.6.9 Controlling Message Verbosity


By default, the register and memory package prints only messages on activity in the registers. You can
have additional messages relating to the register files and address map by changing the logger verbosity
level to high.

To turn on all messages coming from the register and memory package:
• Use the set message command.

Register and Memory Package Version 2.0 1-45


The Register and Memory Package
Accessing Multiple Address Maps on the Bus

For example:
set message @vr_ad_*
Or:

• Use the set_actions() method inside your e code.


For example:
sys.logger.set_actions(NONE,{NORMAL},"vr_ad_*","...",add)

To filter out all messages coming from the register and memory package:
• Use the set message command with the -remove option.
For example:
set message -remove @vr_ad_*
Or:

• Use the set_actions() method inside your e code.


For example:
sys.logger.set_actions(NONE,{NORMAL},"vr_ad_*","...",remove)

The preceding examples assume that the messages are handled by sys.logger. For more information, see
the section on messaging in the e Reuse Methodology (eRM) Developer Manual.

1.6.10 Accessing Multiple Address Maps on the Bus


Some protocols (like the PCI) uses multiple address spaces (MEMORY, IO, CONFIG) on the bus. The
control signals determine which address space to access. The default behavior of vr_ad_sequence_driver
is to work with a single address map specified by a constraint on the addr_map field. Therefore, by
default, sequences can access only registers from one address map.

To enable access of multiple address maps from a single RSD:

1. Label each address map with a different enumerated value, and use
vr_ad_sequence_driver.add_space() to add each address map with its label to the RSD map list.

For example:
extend vr_ad_space_kind : [EX_IO, EX_CONFIG1];
extend ex_c_bus_env {
addr_map1 : vr_ad_map;
addr_map2 : vr_ad_map;
rsd : vr_ad_sequence_driver;

1-46 Version 2.0 Register and Memory Package


The Register and Memory Package
Disabling Comparison for Registers

post_generate() is also {
// Two address spaces can be accessed through the bus
rsd.add_space(addr_map1, EX_CONFIG1);
rsd.add_space(addr_map2, EX_IO);
};
};

2. Use the label in the sequence to specify which address map to access.

For example:
extend MAIN vr_ad_sequence {
!r2 : EX_R2 vr_ad_reg;
// By default, register accesses use the IO space
keep soft addr_space == EX_IO;
body() @driver.clock is only {
...
// Use the CONFIG1 space for this access
write_reg {.addr_space == EX_CONFIG1 } r2 keeping {.data1 == 3};
};
};

3. Extend your vr_ad_execute_op() method to check the vr_ad_operation.addr_space field and


translate it to the appropriate transaction.

1.6.11 Disabling Comparison for Registers


In read transactions, the e model compares the data captured from the bus with the information stored in
model. This is done when an eVC monitor calls the compare_and_update() method. Comparison of
registers is done via a comparison mask. By default, the value of the mask is 0xffffffff, meaning compare
all register bits. Change the mask value lets you control which bits to compare.

To disable comparison for a register (or for part of a register):


• Call the vr_ad_reg.set_compare_mask() method with the appropriate bits of the parameter set to 0.
For example, you could disable comparison of the VR_AD_RX_MODE register as follows:
extend VR_AD_RX_MODE vr_ad_reg {
set_static_info() is {
set_compare_mask(0);
};
};

Register and Memory Package Version 2.0 1-47


The Register and Memory Package
Sparse Memory

1.7 Sparse Memory


The vr_ad_mem struct enables modeling of sparse memory. The sparse memory can be used as a
reference model to a real memory located in the DUT or as an external memory implemented solely in e
(for example, the memory of an eVC slave). Memory that is a reference model is instantiated in the
module eVC or in the passive agent corresponding to the DUT. Memory that is an external memory in e
is instantiated in the corresponding active agent.

Note The sparse memory feature is still at an alpha level of development. For more
information, see the sVM release notes.

This section contains:

• Section 1.7.1, “Instantiating a Memory,” on page 1-48


• Section 1.7.2, “Accessing Memory,” on page 1-49
• Section 1.7.3, “Updating the Memory,” on page 1-50
• Section 1.7.4, “Memory Features,” on page 1-51
• Section 1.7.5, “Storing Complex Structures in Memory,” on page 1-54
• Section 1.7.6, “Accessing Objects in Memory,” on page 1-57

1.7.1 Instantiating a Memory


To instantiate a memory:

1. Extend vr_ad_mem_kind, and add a new kind (according to eRM naming conventions).

For example, you could add the kind EX_MEM as follows:


extend vr_ad_mem_kind : [EX_MEM];

2. Extend the relevant unit by adding a field of the specific vr_ad_mem subtype, and constrain the
memory to the appropriate size.

For example, you could set a 1Kx64 memory as follows:


extend ACTIVE SLAVE vr_xbus_agent {
mem : EX_MEM vr_ad_mem;
keep mem.size == 0x1024;
keep mem.addressing_width_in_bytes == 8;
};

3. Add the memory to the address space using add_with_offset() (same as adding a register file)

1-48 Version 2.0 Register and Memory Package


The Register and Memory Package
Accessing Memory

For example, assuming that the memories of the slaves are mapped in consecutive addresses, you
could map all active XBus slaves as follows:
extend vr_xbus_env {
post_generate() is also {
for each (slave) in active_slaves {
addr_map.add_with_offset(index*1000,slave.mem);
};
};
};

1.7.2 Accessing Memory


As explained in “Basic Register Operations” on page 21, the same vr_ad_operation is used for register
operations (REG vr_ad_operation) and memory operations (MEM vr_ad_operation). The predefined
field mem_op (of type MEM vr_ad_operation) can be used as a sequence item for doing memory
operations. The memory operations are more general and can also access registers (by specifying a
register address).

To access a memory:
• Use the predefined field mem_op as a sequence item and constrain its address, data, and direction.
For example:
extend MAIN vr_ad_sequence {
body() @driver.clock is only {
do mem_op keeping {
.direction == WRITE;
.address == 0x10;
.data == {1;2;3;4;5;6;7;8};
};
};
};

Note The above code has an abbreviated form using the write_mem and read_mem macros.
See “write_mem and read_mem Macros” on page 1-49.

1.7.2.1 write_mem and read_mem Macros


The following macros are provided for reading and writing memories.

Syntax
write_mem [{op-block-constraints}] address write-data-exp [mask]

Register and Memory Package Version 2.0 1-49


The Register and Memory Package
Updating the Memory

read_mem [{op-block-constraints}] address read-list length

Parameters

op-block-constraints Block of constraints for generating the operation fields (MEM


vr_ad_operation)

address Address to be accessed

write-data-exp Data to be written

mask Mask to apply on the written data

read_list List of bytes to be filled by the read operation

length Number of bytes to read

Syntax Example
var data : list of byte;
read_mem 0x100 data 4;
write_mem 0x110 data;

Example
Writing and reading from a memory.
extend vr_ad_sequence_kind : [EX_SEQ1];

extend EX_SEQ1 vr_ad_sequence {


body() @driver.clock is only {
var rdata : list of byte;
write_mem 0x10 0xaabbccdd; // Write to address 0x10
read_mem 0x10 rdata 4; // Read 4 bytes from address 0x10
};
};

1.7.3 Updating the Memory


Once you add the memory to the address map and connect the address map to an eVC monitor, the
memory is updated and automatically compares read data.

For example:
extend vr_xbus_bus_monitor_u {

1-50 Version 2.0 Register and Memory Package


The Register and Memory Package
Memory Features

on transfer_end {
if transfer.read_write == WRITE {
env.address_map.update(transfer.addr,%{transfer.data},{});
} else {
env.address_map.compare_and_update(
transfer.addr,%{transfer.data});
};
};
};

See Also
• “Updating the Register Model Using an eVC Monitor” on page 1-20.

1.7.4 Memory Features


This section contains:

• Section 1.7.4.1, “Reading from and Writing to a File,” on page 1-51


• Section 1.7.4.2, “Controlling Returned Data of Uninitialized Addresses,” on page 1-52
• Section 1.7.4.3, “Side Effects,” on page 1-53
• Section 1.7.4.4, “Memory Backdoor Access,” on page 1-53

1.7.4.1 Reading from and Writing to a File


You can initialize a memory by reading its content from a file. You can also dump a memory content into
a file. The format of the data file is the format which is supported by verilog.

To initialize the memory from a data file:


• Use the method readmemh() (for hex format) or readmemb() (for binary format):
For example:
extend ACTIVE SLAVE vr_xbus_agent {
post_generate() is also {
mem.readmemh("mem_init.txt",
0, MAX_UINT, // Address range of memory to update
0, MAX_UINT); // Address range of file to read
};
};

Register and Memory Package Version 2.0 1-51


The Register and Memory Package
Memory Features

To dump the memory content into a data file:


• Use the method dumpmemh() (for hex format) or dumpmemb() (for binary format):
For example:
extend ACTIVE SLAVE vr_xbus_agent {
finalize() is also {
mem.dumpmemh("mem_data.txt",
0, 0x1000) // Address range of the memory to dump
};
};

1.7.4.2 Controlling Returned Data of Uninitialized Addresses


When the memory is used as an eVC slave memory, you need the ability to control the value of returned
data when reading from uninitialized addresses. By default, reading from an uninitialized address
returns zero. You can change the default behavior to return a random value or a specific value. For more
complex behavior, you can override the memory get_data() method.

To return a random value:


• Constrain the vr_ad_mem.read_default_value field to RANDOM.
For example:
extend ACTIVE SLAVE vr_xbus_agent {
mem : vr_ad_mem;
keep mem.read_default_value == RANDOM;
};

To return a specific value:


• Constrain the vr_ad_mem.read_default_value field to USER_DEFINED and
vr_ad_mem.default_value to your chosen value.
For example:
extend ACTIVE SLAVE vr_xbus_agent {
mem : vr_ad_mem;
keep mem.read_default_value == USER_DEFINED;
keep mem.default_value == 0xaa;
};

To define a particular logic for the returned value:


• Extend the vr_ad_mem.get_data() method for a specific memory subtype, and implement your own
logic in it.

1-52 Version 2.0 Register and Memory Package


The Register and Memory Package
Memory Features

For example:
extend vr_ad_mem_kind : [EX_MEM];
extend ACTIVE SLAVE vr_xbus_agent {
mem : EX_MEM vr_ad_mem;
};
extend EX_MEM vr_ad_mem {
get_data(addr : vr_ad_addr_t, size : uint) : list of byte is only {
if address < 0x100 {
// Set the size of the list and fill it with 0xbb
result.resize(size,TRUE,0xbb,TRUE);
} else {
// Set the size of the list and fill it with 0xaa
result.resize(size,TRUE,0xaa,TRUE);
};
};
};

1.7.4.3 Side Effects


Like any addressable item, the pre_access() memory method is called before an access to the memory,
and the post_access() memory method is called after an access to the memory. You can use these hooks
to implement side effects.

See Also
• “Implementing Side Effects” on page 1-32

1.7.4.4 Memory Backdoor Access


Memory backdoor access lets you directly access a memory implemented in Verilog or VHDL. Like
register access, you must specify the memory backdoor_path and access is done using the read_mem
and write_mem macros with the backdoor flag turned on.

To set the memory backdoor_path:

1. Constrain the vr_ad_mem.backdoor_path to the HDL path name.

For example:
extend ACTIVE SLAVE vr_xbus_agent {
mem : EX_MEM vr_ad_mem;
keep mem.size == 0x1024;
keep mem.backdoor_path == "~/top/sram";
};

Register and Memory Package Version 2.0 1-53


The Register and Memory Package
Storing Complex Structures in Memory

2. (For Verilog designs only) Add a verilog variable.

For example:
verilog variable ’~/top/sram[99:0][7:0]’;

To perform a memory backdoor access:


• Use the read_mem and write_mem macros with the backdoor flag.
For example:
extend vr_ad_sequence_kind : [EX_SEQ2];

extend EX_SEQ2 vr_ad_sequence {


body() @driver.clock is only {
var rdata: list of byte;
write_mem {.backdoor} 0x10 0xaabbccdd; // Write to address 0x10
read_mem {.backdoor} 0x10 rdata 4; // Read 4 bytes from
// address 0x10
};
};

See Also
• “Backdoor Operation” on page 1-36

1.7.5 Storing Complex Structures in Memory


Sometimes you must store complex structures like packets or descriptors in the memory. You might
want to have both a high level (packet) and a low level (list of byte) representation. The following
capabilities are required:

• Generating the object, optionally with constraints


• Allocating address space for the object
• Update the memory with the object content
• Automatic update of the object whenever the memory changes
• Release of object address space
This section contains:

• Section 1.7.5.1, “Creating Memory Objects,” on page 1-55


• Section 1.7.5.2, “Connecting Memory Objects to the Memory,” on page 1-55

1-54 Version 2.0 Register and Memory Package


The Register and Memory Package
Storing Complex Structures in Memory

See Also
• “Accessing Objects in Memory” on page 1-57

1.7.5.1 Creating Memory Objects


Memory objects are created with the mem_obj_def macro.The mem_obj_def macro works almost the
same as the reg_def macro.

Syntax
mem_obj_def obj-name {
mem_fld field-name : field-type [: cov];…
};

Syntax Example
mem_obj_def EX_DESC {
mem_fld kind : uint(bits:2) : cov;
mem_fld data[16] : list of byte : cov;
};

Parameters

obj_name Memory object name. Must follow eRM naming conventions and use a
company prefix

field-name Memory object field name

field-type Memory object field type

cov (Optional) Add coverage for the field

1.7.5.2 Connecting Memory Objects to the Memory


After defining a memory object type, you can generate its content and connect it to the memory by
calling one of the memory methods described in Table 1-7. This allocates (generates) an address space
from the free memory areas using the default memory set (the mem_set field of vr_ad_mem). The
allocation prevents subsequent allocations from using the same address space.

When an object is connected to the memory:

• The memory content can be updated using object methods (see “Methods for Accessing Objects in
Memory” on page 1-58).

Register and Memory Package Version 2.0 1-55


The Register and Memory Package
Storing Complex Structures in Memory

• The object will be updated automatically on any change in the corresponding memory area.
Table 1-7 vr_ad_mem Memory Object Allocation Methods

Method Description

alloc_area(min_addr : vr_ad_addr_t, Allocates an address space using the default memory


max_addr : vr_ad_addr_t) : vr_ad_set set

alloc_obj(addr : vr_ad_addr_t, Allocates address space for a memory object using the
mem_obj : vr_ad_mem_obj) : bool default memory set

alloc_obj_rnd(min_addr : vr_ad_addr_t, Allocates a random address space in


max_addr : vr_ad_addr_t, mem_obj : [min_addr..max_addr] range using the default memory
vr_ad_mem_obj, alignment : uint) : set
vr_ad_addr_t

alloc_obj_from_set(addr : vr_ad_addr_t, Allocates address space using the specified set


mem_obj : vr_ad_mem_obj, set :
vr_ad_set) : bool

alloc_obj_rnd_from_set(min_addr : Allocates a random address space in


vr_ad_addr_t, max_addr : vr_ad_addr_t, [min_addr..max_addr] range using the specified set
mem_obj : vr_ad_mem_obj, set :
vr_ad_set, alignment : uint) :
vr_ad_addr_t

dealloc_area(min_addr : vr_ad_addr_t, Releases an area to the default memory set


max_addr : vr_ad_addr_t)

dealloc_obj(mem_obj : vr_ad_mem_obj) Releases an object to the default memory set

dealloc_obj_to_set(mem_obj : Releases an object to the specified set


vr_ad_mem_obj, set : vr_ad_set)

is_valid(addr : vr_ad_addr_t) : bool Returns whether the address contains valid data

get_mem_obj_by_address(addr : Returns the memory object that is located at the


vr_ad_addr_t) specified address

Example
You could allocate address space for a list of descriptors as follows:
extend ex_c_bus_env {
mem : vr_ad_mem;
keep mem.mem_size == 1000;

1-56 Version 2.0 Register and Memory Package


The Register and Memory Package
Accessing Objects in Memory

post_generate() is also {
addr_map.add_with_offset(0x100,mem);
};
};

extend MAIN vr_ad_sequence {


descriptors[16] : list of EX_DESC vr_ad_mem_obj;
body() @driver.clock is only {
// Reference to the memory
var mem : vr_ad_mem = driver.addr_map.get_mem_by_address(0x100);
for each (desc) in descriptors {
// Allocate a space from the desriptor
desc_addr = mem.alloc_obj_rnd(0, 1000, desc, 1);
};
};
};

1.7.6 Accessing Objects in Memory


This section contains:

• Section 1.7.6.1, “write_mem_obj and read_mem_obj Macros,” on page 1-57


• Section 1.7.6.2, “Methods for Accessing Objects in Memory,” on page 1-58

1.7.6.1 write_mem_obj and read_mem_obj Macros


The following macros are provided for reading and writing objects in memory.

Syntax
write_mem_obj [{op-block-constraints}] object

read_mem_obj [{op-block-constraints}] object

Parameters

op-block-constraints Block of constraints for generating the operation fields (MEM


vr_ad_operation)

object A memory object instance

Register and Memory Package Version 2.0 1-57


The Register and Memory Package
Accessing Objects in Memory

Syntax Example
read_mem_obj desc;
write_mem_obj desc;

Example
You could read a descriptor from the memory, modify it, and write it back to the memory as follows:
extend vr_ad_sequence_kind : [EX_SEQ1];

extend EX_SEQ1 vr_ad_sequence {


!cur_desc : EX_DESC vr_ad_mem_obj;
body() @driver.clock is only {
// Reference to the memory
var mem : vr_ad_mem =
driver.addr_map.get_mem_by_address(0x100);
var desc_addr : vr_ad_addr_t;
gen cur_desc;
// Allocate random space in range [0..200] with alignment of 4
desc_addr = mem.alloc_obj_rnd(0, 200, cur_desc, 4);
// Read the content of the descriptor from the memory, modify
// it, and write it back to the memory
read_mem_obj cur_desc;
cur_desc.kind = B;
write_mem_obj cur_desc;
};
};

1.7.6.2 Methods for Accessing Objects in Memory


When you change a memory object field, the memory does not update automatically. You must manually
update the memory. You can use the write_mem_obj macro described in “write_mem_obj and
read_mem_obj Macros” on page 1-57 to update the memory using bus transactions. The backdoor
method for doing this depends on whether the memory is an HDL memory or an e model

Table 1-8 describes the methods that let you access the e model or HDL memory after connecting the
memory object to the memory.

Table 1-8 vr_ad_mem_obj Methods

Method Description

update_model() Writes the current content of the object into the e model

1-58 Version 2.0 Register and Memory Package


The Register and Memory Package
Register and Memory Data Structures

Table 1-8 vr_ad_mem_obj Methods (continued)

Method Description
write_obj_val_backdoor() Write the current content of the object into the HDL
memory using backdoor access

read_obj_val_backdoor() Reads the current content of the object from the memory
using backdoor access

1.8 Register and Memory Data Structures


This section contains:
• Section 1.8.1, “Type Naming Conventions,” on page 1-59
• Section 1.8.2, “Type Hierarchy,” on page 1-60
• Section 1.8.3, “Register Attribute Structs,” on page 1-60
• Section 1.8.4, “vr_ad_operation,” on page 1-61
• Section 1.8.5, “vr_ad_reg,” on page 1-61
• Section 1.8.6, “vr_ad_reg_static_info,” on page 1-73
• Section 1.8.7, “vr_ad_reg_file,” on page 1-74
• Section 1.8.8, “vr_ad_map,” on page 1-78
• Section 1.8.9, “vr_ad_mem,” on page 1-86
• Section 1.8.10, “vr_ad_sequence_driver,” on page 1-90

1.8.1 Type Naming Conventions


Table 1-9 shows the type naming conventions used in the register and memory package.

Table 1-9 Register and Memory Package Type Naming Conventions

Type Name Prefix

Registers and memory vr_ad

Registers only vr_ad_reg

Memory only vr_ad_mem

Register and Memory Package Version 2.0 1-59


The Register and Memory Package
Type Hierarchy

1.8.2 Type Hierarchy


The addressable items that are implemented in this package are vr_ad_reg, vr_ad_reg_file, and
vr_ad_map. A common base type vr_ad_base provides common interfaces for all of the addressable
items.

Address maps and register files contain a list of addressable items (of type vr_ad_base). Therefore, they
can hierarchically contain other address maps, register files, and registers. The following methods are
common to all addressable items:

• update(addr : vr_ad_addr_t, data : list of byte, user_mask : list of byte)


• fetch(addr : vr_ad_addr_t, size : vr_ad_addr_t): list of byte
• compare_and_update(addr : vr_ad_addr_t, expected_data : list of byte): bool
• get_size(): int(bis:*)
• reset()

1.8.3 Register Attribute Structs


Register-related attributes are sorted into three structs according to their purpose. This can facilitate
generation of registers on the fly.

For example, an attribute like the write mask is relevant only when you update the e reference model and
should be generated only once, at the beginning of the test. Therefore, it is located in the
vr_ad_reg_static_info struct, which is generated only once.

An attribute like direction (read or write) describes an operation done on a register. It is not an integral
part of a register. Therefore, it is best to locate it in the vr_ad_operation struct.
Table 1-10 describes the structs used to implement the various aspects of registers.

Table 1-10 Register-Related Structs

Struct Description

vr_ad_operation Attributes of the operation performed on the register

vr_ad_reg Physical field of the register

vr_ad_reg_static_info Attributes that are not generated on the fly

Figure 1-1 shows how the register attributes are divided. (Only the most important fields are listed.)

1-60 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_operation

Figure 1-1 Register Data Structure

Operation (REG Register (vr_ad_reg): Static information


vr_ad_operation): kind: vr_ad_reg_kind (vr_ad_reg_static_info):
reg: vr_ad_reg !static_info: offset: vr_ad_addr_t
dest_sd: vr_ad_reg_static_info size: uint
any_sequence_driver %field1: reset_value: vr_ad_data_t
direction: vr_ad_rw_t %field2: wmask: vr_ad_data_t
backdoor_access: bool ... compare_mask: bool

See Also
• vr_ad_operation on page 1-61
• vr_ad_reg on page 1-61
• vr_ad_reg_static_info on page 1-73

1.8.4 vr_ad_operation
vr_ad_operation is the data item (sequence item) for register and memory accesses. It encapsulates all
attributes that describe the operation to be done on the register (like direction). For more information,
see “Basic Register Operations” on page 1-21.

1.8.5 vr_ad_reg
The different register types are modeled using when inheritance. For each register type, a new subtype
of vr_ad_reg_kind is created and the physical fields are added to the specific subtype of vr_ad_reg.
Typically, the definition of a new register is done with the reg_def macro described in “Defining
Registers with the reg_def Macro” on page 1-9.

Table 1-11 Main Register Operations

Method Operation

write_reg_val() Write a value into an e model register, applying the write mask

read_reg_val() Read a register content

write_reg_raw() Write a value into the e model register

write_reg_rawval() Update register content with the specified data

Register and Memory Package Version 2.0 1-61


The Register and Memory Package
vr_ad_reg

Table 1-11 Main Register Operations (continued)

Method Operation

set_static_info() Set register static information, hook method


set_write_mask() Set a write mask (mainly for registers with multiple write masks)

set_read_mask() Set a read mask (mainly for registers with multiple read masks)

set_compare_mask() Set a compare mask

set_backdoor_path() Set the backdoor path of a register

set_field_backdoor_path() Set the backdoor path for a single register field

update() Update the e model register

compare_and_update() Read from the e model and compare with a given list of byte

post_access() Hook method, called immediately after update(), fetch(), or


compare_and_update()

For a list of all fields and methods of vr_ad_reg, see “Fields and Methods of vr_ad_reg” on page 1-71.

1.8.5.1 write_reg_val()

Syntax
write_reg_val(data : vr_ad_data_t)

Parameters

data Value to write

Description
This method updates register content. The parameter for this method is the vr_ad_data_t type value to be
updated (as opposed to a list of bytes in the update() method). The data in this method is anded with the
write mask before it is written to the register. When using this method, the post_access() hook for side
effect is not called, and no coverage is collected.

1-62 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_reg

Example
extend EX_TX_MODE vr_ad_reg {
post_access(direction : vr_ad_rw_t) is {
write_reg_val(0xffffffff);
};
};

1.8.5.2 read_reg_val()

Syntax
read_reg_val(): vr_ad_data_t

Description
This method returns the current value of the register. The returned value is of type vr_ad_data_t. When
using this method, the post_access() hook for side effect is not called, and no coverage is collected.

Example
extend ex_c_bus_driver {
reg_seq : REG_SEQ ex_c_bus_sequence;
keep reg_seq.driver == me;
vr_ad_execute_op(op_item : vr_ad_operation) : list of byte @clock is {
if op_item is a REG vr_ad_operation (reg_op) {
if op_item.direction == WRITE {
reg_seq.write(op_item.address,
reg_op.reg.read_reg_val());
}
};
};
};

1.8.5.3 write_reg_raw()

Syntax
write_reg_raw(offset : vr_ad_addr_t, data : vr_ad_data_t, mask : vr_ad_data_t)

Register and Memory Package Version 2.0 1-63


The Register and Memory Package
vr_ad_reg

Parameters

offset Bit offset

data Data to be stored in the register model

mask Mask to be applied to the operation

Description
This method updates register content. The data is shifted with the offset before being written. The
method does not consider the static_info write mask, but it is masked with the mask parameter. If no
mask is needed use 0xffffffff (or ~0). When using this method, the post_access() hook for side effect is
not called, and no coverage is collected.

Example
This example shows how to clear register VR_AD_R2 when the clear_r2 field of register VR_AD_R1 is
set to 1.
extend VR_AD_R1 vr_ad_reg {
post_access(direction : vr_ad_rw_t) is {
if clear_r2 == 0x1 {
// Locate target register
var my_reg_file : SIDE_EFFECT_FILE vr_ad_reg_file =
get_parents()[0].as_a(SIDE_EFFECT_FILE vr_ad_reg_file);
// Set the value of the target register
my_reg_file.vr_ad_r2.write_reg_raw(0,0x0,0xffffffff);
};
};
};

1.8.5.4 write_reg_rawval()

Syntax
write_reg_rawval(data : vr_ad_data_t)

Parameters

data Data to be stored in the register model

1-64 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_reg

Description
This method updates register content with the specified data. It does not consider any mask — the data
is written as is.When using this method, the post_access() hook for side effect is not called, and no
coverage is collected.

Example
This example shows how to clear register VR_AD_R2 when the clear_r2 field of register VR_AD_R1 is
set to 1.
extend VR_AD_R1 vr_ad_reg {
post_access(direction : vr_ad_rw_t) is {
if clear_r2 == 0x1 {
// Locate target register
var my_reg_file : SIDE_EFFECT_FILE vr_ad_reg_file =
get_parents()[0].as_a(SIDE_EFFECT_FILE vr_ad_reg_file);
// Set the value of the target register
my_reg_file.vr_ad_r2.write_reg_rawval(0x0);
};
};
};

1.8.5.5 set_static_info()

Syntax
set_static_info()

Description
The reg_def macro sets only the write mask and reset value. Other optional static information like
backdoor path and description must be set by the set_static_info() method.

Example
reg_def R1 {
reg_fld data : uint(bits:32) : RW : 0;
set_static_info() is {
set_backdoor_path("r1");
};
};

Register and Memory Package Version 2.0 1-65


The Register and Memory Package
vr_ad_reg

1.8.5.6 set_write_mask()

Syntax
set_write_mask(wmask : vr_ad_data_t, file_or_map : vr_ad_group)

Parameters

wmask Write mask

file_or_map Register file or map where the write mask is applied

Description
This method sets the write mask of a register. Sometimes the write-mask value of a register depends on
the address space where the register is accessed. It could be R (read only) when accessing from one
address space or RW (read-write) when accessing from another address space. The set_write_mask()
method lets you specify a write-mask value for a specific address map. If no map is specified, then the
write-mask value is fixed and does not depend on the address map from which it is accessed.

Example
reg_def EX_R1 EX_FILE 0x0 {
reg_fld data2 : uint(bits:8) : RW : 0; // [23:16]
reg_fld data1 : uint(bits:8) : RW : 0; // [15: 8]
reg_fld data0 : uint(bits:8) : RW : 0; // [ 7: 0]
};
extend ex_c_bus_env {
addr_map1 : vr_ad_map;
addr_map2 : vr_ad_map;
ex_file : EX_FILE vr_ad_reg_file;
post_generate() is also {
// EX_FILE register file is mapped on both address maps with
// different offsets.
addr_map1.add_with_offset(0x00000, ex_file);
addr_map2.add_with_offset(0x01000, ex_file);
// EX_R1 has 2 masks:
// RW - when accessed from addr_map1 (as specified by the macro).
// RO - when accessed from addr_map2.
ex_file.ex_r1.set_write_mask(0x0,addr_map2);
};
};

1-66 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_reg

1.8.5.7 set_read_mask()

Syntax
set_read_mask(rmask : vr_ad_data_t, file_or_map : vr_ad_group)

Parameters

rmask Read mask

file_or_map Register file or map where the read mask is applied

Description
This method sets the register’s read mask. If the read-mask value is applicable only when accessing the
register through a specific address map (or register file), you must use the address map (or register file)
for the file_or_map parameter. Otherwise, use NULL.

Example
reg_def EX_R1 EX_FILE 0x0 {
reg_fld data2 : uint(bits:8) : RW : 0; // [23:16]
reg_fld data1 : uint(bits:8) : RW : 0; // [15: 8]
reg_fld data0 : uint(bits:8) : RW : 0; // [ 7: 0]
set_static_info() is also {
set_read_mask(0xff00ff,NULL);
// Note that the above setting is equivalent to writing:
// reg_fld data1 : uint(bits:8) : W : 0;
// in the reg_def macro.
};
};

1.8.5.8 set_compare_mask()

Syntax
set_compare_mask(compare_mask : vr_ad_data_t)

Parameters

compare-mask Compare mask

Register and Memory Package Version 2.0 1-67


The Register and Memory Package
vr_ad_reg

Description
Excludes some fields from comparison.

Example
reg_def R1 {
reg_fld status : uint(bits:32) : R : 0;
set_static_info() is {
set_compare_mask(0);
};
};

1.8.5.9 set_backdoor_path()

Syntax
set_backdoor_path(path : string)

Parameters

path HDL path of the register for backdoor access

Description
Sets the backdoor path of a register. The register backdoor mechanism uses this string to write
(write_reg_val_backdoor()) or to read (read_reg_val_backdoor()).

Example
reg_def R1 {
reg_fld status : uint(bits:32) : RW : 0;
set_static_info() is {
set_backdoor_path(“r1”);
};
};

1-68 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_reg

1.8.5.10 set_field_backdoor_path()

Syntax
set_field_backdoor_path(field_name : string, path : string)

Parameters

field_name Field name

path HDL path of the field for backdoor access

Description
Sets the backdoor path of a single register field. To be used when each register field has a different HDL
path.

Example
reg_def R1 {
reg_fld ctrl1 : uint(bits:8) : RW : 0;
reg_fld ctrl2 : uint(bits:8) : RW : 0;
set_static_info() is {
set_backdoor_path("ctrl1","~/top/ctrl1");
set_backdoor_path("ctrl2","~/top/ctrl2");
};
};

1.8.5.11 update()

Syntax
update(addr : vr_ad_addr_t, data : list of byte, mask : list of byte)

Parameters

addr Offset from which to start writing the data.

data List of byte to write

Register and Memory Package Version 2.0 1-69


The Register and Memory Package
vr_ad_reg

mask List of byte to be used as masks. Each element in the list masks the
equivalent element in the data list. 0x0 masks out a byte, and 0xff writes
the data as is. An empty list “{}” indicates that no masking is applied

Description
Use this method when you need to update a specific e model register. Usually, you use the address 0,
meaning write from the beginning of the register. You can also use non-zero offsets if the register is in a
register file. If you update a register and you specify a mask, the mask will be anded with the wmask of
the register. Whenever this method is called, the pre_access() and post_access() hooks are activated,
and coverage of the register is collected with direction WRITE.

Example
extend vr_xbus_bus_monitor_u {
on transfer_end {
if transfer.read_write == WRITE {
reg_file.tx_data.update(0,%{transfer.data},{});
};
};
};

1.8.5.12 compare_and_update()

Syntax
compare_and_update(addr : vr_ad_addr_t, expected_data : list of byte): bool

Parameters

address Offset from which to start reading the data

expected_data List of bytes to be compared to the data stored in the e model

Description
Use this method to compare a specific register with given data. Typically, you use the address 0, meaning
comparing from the beginning of the register. You can also use non-zero offsets if the register is in a
register file. Comparison is done only for the number of bytes given as the expected data. An error is

1-70 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_reg

issued only for a mismatch in a register whose compare_mask bits are set. Whenever this method is
called, the pre_access() and post_access() hooks are activated, and coverage of registers is collected
with direction READ.

Example
extend vr_xbus_bus_monitor_u {
on transfer_end {
if transfer.read_write == READ {
compute p_xbus_env.addr_map.compare_and_update(transfer.addr,
%{transfer.data});
};
};
};

1.8.5.13 post_access()

Syntax
post_access()

Description
This method is a user hook for implementing features like “clear on read” and “clear on write”.

Example
extend EX_REGS_TX_MODE vr_ad_reg {
// Clear on Write
post_access(direction : vr_ad_rw_t) is {
if direction == write{
write_reg_raw(0x0,0x0,0xffffffff);
};
};
};

See Also
• “Implementing Side Effects” on page 1-32

1.8.5.14 Fields and Methods of vr_ad_reg


• “vr_ad_reg Fields” on page 72

Register and Memory Package Version 2.0 1-71


The Register and Memory Package
vr_ad_reg

• “vr_ad_reg Methods” on page 72


Table 1-12 vr_ad_reg Fields

Field Description

kind: vr_ad_reg_kind Register kind

static_info: Static information of the register (masks, reset value…)


vr_ad_reg_static_info

Table 1-13 vr_ad_reg Methods

Method Description

compare_and_update(addr : Read from the e model and compare it with a given list of
vr_ad_addr_t, data : list of byte): bool byte

fetch(addr : vr_ad_addr_t, size : uint): Read from the e model


list of byte

get_indirect_addr(map : vr_ad_map) Return the offset of an unmapped register

get_packing_option(): pack_options Packing option of the register, taken from the register file

get_size(): int(bits: *) Return the register size in bytes

post_access(direction : vr_ad_rw_t) Hook method, called immediately after update() and


fetch()

read_reg_rawval() : vr_ad_data_t Read register content without applying rmask

read_reg_val(): vr_ad_data_t Read register content (applying rmask)

read_reg_val_backdoor(): Hook method, backdoor read of HDL register


vr_ad_data_t:
uint(bits:VR_AD_DATA_WIDTH)

reset() Reset the register by restoring its reset value

set_static_info() User hook to set register static information

set_write_mask( Set a write mask. This method must be used if a single


wmask : vr_ad_data_t, register has different masks when accessed from different
map : vr_ad_group) address spaces. See set_write_mask() on page 1-66

1-72 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_reg_static_info

Table 1-13 vr_ad_reg Methods (continued)

Method Description

update(addr : vr_ad_addr_t, Update the e model register


data : list of byte,
mask : list of byte)

write_reg_raw(offset : uint, data : Write a uint into a register without applying the wmask
vr_ad_data_t, mask : vr_ad_data_t)

write_reg_rawval(data : Write a uint into a register without applying the wmask.


vr_ad_data_t) This is a simplified form of write_reg_raw()

write_reg_val(data : vr_ad_data_t) Write a uint into a register

write_reg_val_backdoor(data : Hook method, backdoor write of HDL register


vr_ad_data_t:
uint(bits:VR_AD_DATA_WIDTH))

1.8.6 vr_ad_reg_static_info
The vr_ad_reg_static_info struct contains register attributes that should not be generated on the fly when
doing register operations. The static information struct is created only when you add a register to a
register file or to an address map (by add_with_offset()). You can set some fields using
set_static_info() or the reg_def macro. Other fields are automatically updated by the e model.

Table 1-14 vr_ad_reg_static_info Fields

Field Description

backdoor_path: string HDL path for backdoor access

compare_mask: vr_ad_data_t Disables comparison of register data when set to 0. Can be


used to mask all or part of a register

cur_value: vr_ad_data_t Current value (read-only)

description: string Description of the register

direction: vr_ad_rw_t Direction of the register access (READ or WRITE),


stored here for coverage (read-only)

prev_value: vr_ad_data_t Value before last update (read-only)

reset_value: vr_ad_data_t Value to be set on reset (set in the reg_def macro)

Register and Memory Package Version 2.0 1-73


The Register and Memory Package
vr_ad_reg_file

Table 1-14 vr_ad_reg_static_info Fields (continued)

Field Description

rmask: vr_ad_data_t Read mask (updated automatically in the reg_def macro


when “W” is specified for the field mask)

size: uint Size of the register in bytes (read-only)

wmask: vr_ad_data_t Write mask (updated automatically in the reg_def macro


when “R” is specified for the field mask)

written_data: list of byte Original data before masking (read-only)

1.8.7 vr_ad_reg_file
The register file contains a list of registers (or register files) referenced by vr_ad_node. The
implementation assumes that a register can be accessed through several addresses, and therefore the
address is stored in address nodes rather than the register itself.

Figure 1-1 Register File Nodes

Register File
ad_nodes : list of vr_ad_node

offset 0x0 vr_ad_tx_mode


ad_item register

offset 0x1 vr_ad_tx_data


ad_item register

offset 0x2 vr_ad_rx_mode


ad_item register

offset 0x3 vr_ad_rx_data


ad_item register

Each vr_ad_node contains an address and a reference to a register, a register file, or a memory block.

1-74 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_reg_file

Table 1-15 vr_ad_node Fields

Field Description

ad_item: vr_ad_base Reference to an addressable item: register, mem, reg_file,


or map

offset: vr_ad_addr_t Offset from the container base address

size: uint Size of the addressable item

All offsets are relative to the base address of the containing object. The absolute address is calculated by
totaling all offsets from the addressable item to the top address map.

Table 1-16 Main Register File Operations

Method Operation

add_with_offset() Manually add registers to a register file

For a list of all fields and methods of vr_ad_reg_file, see “Fields and Methods of vr_ad_reg_file” on page
1-76.

1.8.7.1 add_with_offset()

Syntax
add_with_offset(offset : vr_ad_addr_t, ad_item : vr_ad_base)

Parameters

offset The desired base address of the addressable item

ad_item The addressable item to be added to the register file

Description
This method creates an address node with a reference to the register and holds the address of the item.
The parameters for this method are the offset of the register and the register to be added. The reg_def
macro uses this method to automatically add a register to a register file. Explicitly use this method when
a register file contains multiple instances of a register type.

Register and Memory Package Version 2.0 1-75


The Register and Memory Package
vr_ad_reg_file

Example
extend XCORE vr_ad_reg_file {
%tx_mode_regs[4] : list of EX_REGS_TX_MODE vr_ad_reg;
post_generate() is also {
for each (reg) in tx_mode_regs {
add_with_offset(index*4,reg);
};
};
};

1.8.7.2 Fields and Methods of vr_ad_reg_file


• “vr_ad_reg_file Fields” on page 76
• “vr_ad_reg_file Methods” on page 77
Table 1-17 vr_ad_reg_file Fields

Field Description

ad_nodes: list (key: offset) of List of all addressable items mapped inside the object
vr_ad_node

addressing_width_in_bytes Width of each address entry in bytes. See “Customizing


Addressing Width” on page 1-44

has_checks Controls whether to have automatic compare checks.


Default is TRUE

has_coverage Controls whether to have automatic coverage.


Default is TRUE

indirect_seq_name: Name of the sequence to perform for access. Used only


vr_ad_sequence_kind for indirect register files

kind: vr_ad_reg_file_kind Register file kind

offset: vr_ad_addr_t Address of the register file

size: vr_ad_addr_t Number of addresses occupied by the register file. By


default, the size is 0

1-76 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_reg_file

Table 1-18 vr_ad_reg_file Methods

Method Description

add_with_offset(offset : vr_ad_addr_t, Adds an addressable item using the specified offset


ad_item : vr_ad_base)

compare_and_update(addr : Compares the given data read on the bus with the e model.
vr_ad_addr_t, data : list of byte): bool Updates the e model if needed

fetch(addr : vr_ad_addr_t, size : uint): Reads from the e model


list of byte

get_address_by_instance(ad_item : Returns the addresses of an item; an item may have no


vr_ad_base): list of vr_ad_addr_t address (not mapped) or several address (mapped in
several addresses)

get_all_nodes(): list of vr_ad_node Returns the address node list of all addressable items

get_all_nodes_in_range(min_addr : Gets all address nodes in the specified range


vr_ad_addr_t, max_addr :
vr_ad_addr_t): list of vr_ad_node

get_all_reg_files(): list of Returns all register files, including unmapped register files
vr_ad_reg_file

get_all_regs(): list of vr_ad_reg Returns all registers, including unmapped registers

get_by_address(addr : vr_ad_addr_t): Gets items by address


vr_ad_base

get_reg_by_address(addr : Gets a register by address


vr_ad_addr_t): vr_ad_reg

get_reg_by_kind(kind : Returns the register of the specified kind; if not unique, an


vr_ad_reg_kind): vr_ad_reg error is issued

get_reg_file_by_address(addr : Returns a register file according to the specified address


vr_ad_addr_t): vr_ad_reg_file

get_reg_file_by_kind(kind : Returns the register file of the specified kind, or error if


vr_ad_reg_file_kind): list of there is more than one instance of this kind
vr_ad_reg_file

get_reg_files_by_kind(kind : Returns all the register files of the specified kind


vr_ad_reg_file_kind): list of
vr_ad_reg_file

Register and Memory Package Version 2.0 1-77


The Register and Memory Package
vr_ad_map

Table 1-18 vr_ad_reg_file Methods (continued)

Method Description

get_regs_by_kind(kind : Returns all registers of the specified kind


vr_ad_reg_kind): list of vr_ad_reg

is_used(addr : vr_ad_addr_t) : bool Returns whether the address is occupied by an


addressable item.

remove(ad_item : vr_ad_base) Removes the item

reset() Reset all registers in the register file

report() ASCII report of the addressable item

set_indirect_seq_name(kind : Sets the name of the indirect access sequence


vr_ad_sequence_kind)

update(addr : vr_ad_addr_t, data: list Updates the e model


of byte, mask : list of byte)

1.8.8 vr_ad_map
The address map has all of the functionality of a register file (see “vr_ad_reg_file” on page 1-74). In
addition, it has address management capabilities (allocation and release of address ranges). The address
management capabilities are discussed in Chapter 1 “The Register and Memory Package”.

The address map contains a list of register files and memory banks with their absolute addresses. The
address map also manages the unmapped (indirect) register maps, even though they are not mapped in
the address space.

Table 1-19 Main Address Map Operations

Method Operation

add_with_offset() Assign an absolute address to an addressable item (register, register


file, or memory bank).

add_to_addr_map() Assign an address to an addressable item (register, register file, or


memory bank) in a particular address range.

add_unmapped_item() Register an unmapped register file.

update() Update the e model.

fetch() Read a list of bytes from the e model.

1-78 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_map

Table 1-19 Main Address Map Operations (continued)

Method Operation
compare_and_update() Read a list of bytes from the e model, and compare it with an
expected list of bytes.

For a full list of all register-related fields and methods of vr_ad_map, see “Fields and Methods of
vr_ad_map” on page 1-84.

1.8.8.1 add_with_offset()

Syntax
add_with_offset(offset : vr_ad_addr_t, ad_item : vr_ad_base)

Parameters

offset The desired base address for the addressable item

ad_item The addressable item to be added to the address map

Description
This method adds an addressable item to the address map at the specified offset. It allocates the required
address space from the free_addrs set and creates an address node with the specified address and a
reference to the addressable item. If the method fails to add the addressable item, an error message is
issued.

Example
extend ex_c_bus_env {
xcore_reg_file : XCORE vr_ad_reg_file;
post_generate() is also {
// Add a reg-file to the address map
addr_map.add_with_offset(0x0,xcore_reg_file);
};
};

Register and Memory Package Version 2.0 1-79


The Register and Memory Package
vr_ad_map

1.8.8.2 add_to_addr_map()

Syntax
add_to_addr_map(min_addr : vr_ad_addr_t, max_addr : vr_ad_addr_t,
ad_item : vr_ad_base, alignment : uint): vr_ad_addr_t

Parameters

min_addr Lower bound of the allocated address space

max_addr Upper bound of the allocated address space

ad_item Addressable item to be added to the address map

alignment Alignment of the allocated address space. For example, 2 aligns to


halfword and 4 aligns to word

Description
This method adds an addressable item to the address map (similar to add_with_offset()). It lets you
specify the alignment and a range from which to allocate the addresses for the addressable item. The
allocated size will be the size of the addressable item. It creates an address node with the allocated base
address and a reference to the addressable item. The returned value is the allocated base address. If
allocation fails, the returned value is UNDEF.

Example
extend ex_c_bus_env {
xcore_reg_file : XCORE vr_ad_reg_file;
!xcore_base_address : vr_ad_addr_t;
post_generate() is also {
// Add a reg-file to the address map
xcore_base_address=
addr_map.add_to_addr_map(0x0,0x1000,xcore_reg_file,4);
};
};

1-80 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_map

1.8.8.3 add_unmapped_item()

Syntax
add_unmapped_item(reg_file : vr_ad_reg_file)

Parameters

reg_file The register file to be added to the address map

Description
This method adds the reg_file and its registers into the reg_list and reg_file_list of the address map lists.
All unmapped register files must be registered in the address map by using this method.

Example
extend ex_c_bus_env {
ycore_reg_file : YCORE vr_ad_reg_file;

post_generate() is also {
// Add the unmapped reg file to the address map
addr_map.add_unmapped_item(ycore_reg_file);
};
};

1.8.8.4 update()

Syntax
update(addr : vr_ad_addr_t, data : list of byte, mask : list of byte)

Parameters

addr Address from which to start writing the data

data List of byte to write

mask List of byte to be used as masks. Each element in the list masks the
equivalent element in the data list. 0x0 masks out a byte, and 0xff writes
the data as is. An empty list “{}” indicates that no masking is applied

Register and Memory Package Version 2.0 1-81


The Register and Memory Package
vr_ad_map

Description
This method updates the e model. For example, it can update on the basis of information gathered by the
monitor. If you update a register and you specify a mask, the mask will be anded with the wmask of the
register. Whenever this method is called, the pre_access() and post_access() hooks are activated, and
coverage of registers is collected with direction WRITE.

Example
extend vr_xbus_bus_monitor_u {
on transfer_end {
if transfer.read_write == WRITE {
reg_file.update(transfer.addr,%{transfer.data},
{0x0;0xff;0xff;0xff});
// The update() mask is: 0xffffff00
// Wmask can be, for example: 0x00ffffff
// The actual mask that will be used is: 0x00ffff00
};
};
};

1.8.8.5 fetch()

Syntax
fetch(addr :vr_ad_addr_t, size : vr_ad_addr_t): list of byte

Parameters

addr Address from which to start reading the data

size Number of bytes to read

Description
This method reads the specified number of bytes from the e model starting from the specified address.
The address does not have to be aligned to the register boundaries. So, for example, it is legal to start
reading from a second byte of a register. The method recursively calls the fetch methods of the
addressable items inside the address map until it gets to a register that returns its packed value. If there
is a gap between two registers, the gap will be padded with 0s. Whenever this method is called, the
pre_access() and post_access() hooks are activated, and coverage of registers is collected with direction
READ.

1-82 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_map

Example
extend vr_xbus_bus_monitor_u {
on transfer_end {
if transfer.read_write == READ{
read_data = p_xbus_env.addr_map.fetch(transfer.addr,4);
};
};
};

1.8.8.6 compare_and_update()

Syntax
compare_and_update(addr : vr_ad_addr_t, expected_data : list of byte): bool

Parameters

address Address from which to start reading the data

expected_data List of bytes to be compared to the data stored in the e model

Description
This method can be used to automatically compare the data captured on the bus with the data that is
stored in the e reference model. The comparison is done only for the number of bytes given as the
expected data. It does not have to be aligned to the register boundaries. An error is issued only for a
mismatch in a register whose compare_mask bits are set. Whenever this method is called, the
pre_access() and post_access() hooks are activated, and coverage of registers is collected with direction
READ.

Example
extend vr_xbus_bus_monitor_u {
on transfer_end {
if transfer.read_write == READ {
compute p_xbus_env.addr_map.compare_and_update(transfer.addr,
%{transfer.data});
};
};
};

Register and Memory Package Version 2.0 1-83


The Register and Memory Package
vr_ad_map

1.8.8.7 Fields and Methods of vr_ad_map


• “vr_ad_map Register-Related Fields” on page 84
• “vr_ad_map Register-Related Methods” on page 84
Table 1-20 vr_ad_map Register-Related Fields

Field Description

addr_alignment: uint Default value of alignment for address allocations. For


example, 2 aligns to halfword and 4 aligns to word

free_addrs: vr_ad_set Address set of free areas

kind: vr_ad_map_kind Address map kind

occupied_addrs: vr_ad_set Address set of mapped areas

reg_file_list: list of vr_ad_reg_file All register files related to the address map

reg_list: list (key: it) of All registers related to the address map
vr_ad_reg_base

size: vr_ad_addr_t Number of addresses occupied by the address map. By


default, the address map occupies the whole address space.
If the actual size of your address map is smaller, then
constrain this field to the actual size

Table 1-21 vr_ad_map Register-Related Methods

Method Description

add_to_addr_map(addr : vr_ad_addr_t, Allocates addresses for an addressable item and adds


ad_item : vr_ad_base, alignment : uint): the item to the address map
vr_ad_addr_t

add_unmapped_item(reg_file : Adds an unmapped register file to the address map


vr_ad_reg_file)

add_with_offset(offset : vr_ad_addr_t, Adds an addressable item using the specified offset


item : vr_ad_base)

compare_and_update(addr : Compares the given data read on the bus with the
vr_ad_addr_t, data : list of byte): bool e model. Updates the e model if needed

fetch(addr : vr_ad_addr_t, size : uint): list Reads from the e model


of byte

1-84 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_map

Table 1-21 vr_ad_map Register-Related Methods (continued)

Method Description

get_address_by_instance(ad_item : Returns the addresses of an item; an item may have


vr_ad_base): list of vr_ad_addr_t no address (not mapped) or several address (mapped
in several addresses)

get_all_nodes(): list of vr_ad_node Returns the address node list of all addressable items

get_all_nodes_in_range(min_addr : Gets all addressable items in the specified range


vr_ad_addr_t, max_addr : vr_ad_addr_t):
list of vr_ad_node

get_all_reg_files(): list of vr_ad_reg_file Gets all address nodes in the specified range

get_all_regs(): list of vr_ad_reg Returns all registers, including unmapped registers

get_by_address(addr : vr_ad_addr_t): Gets items by address


vr_ad_base

get_mem_by_address(addr : Returns the memory instance located at the specified


vr_ad_addr_t) address

get_reg_by_address(addr : vr_ad_addr_t): Gets a register by address


vr_ad_reg

get_reg_by_kind(kind : vr_ad_reg_kind): Returns register of the specified kind, or error if there


vr_ad_reg is more than one instance of this kind

get_reg_file_by_address(addr : Returns a register file according to the specified


vr_ad_addr_t): vr_ad_reg_file address

get_reg_file_by_kind(kind : Returns the register file of the specified kind, or error


vr_ad_reg_file_kind): list of vr_ad_reg_file if there is more than one instance of this kind

get_reg_files_by_kind(kind : Returns all the register files of the specified kind


vr_ad_reg_file_kind): list of vr_ad_reg_file

get_regs_by_kind(kind : vr_ad_reg_kind): Returns all registers of the specified kind


list of vr_ad_reg
lock_item(item : vr_ad_base): bool Locks an addressable item, preventing other
sequences from using it

release_item(item : vr_ad_base) Releases an addressable item

remove(ad_item : vr_ad_base) Removes the item

Register and Memory Package Version 2.0 1-85


The Register and Memory Package
vr_ad_mem

Table 1-21 vr_ad_map Register-Related Methods (continued)

Method Description

reset() Reset all registers in the address map

update(addr : vr_ad_addr_t, data: list of Updates the e model


byte, mask : list of byte)

See Also
• “Address Management (Sets)” on page 1-91

1.8.9 vr_ad_mem
The vr_ad_mem struct provides sparse memory functionality.

Table 1-22 Main Memory Operations

Method Operation

readmemh() Loads values from a file into the memory.

dumpmemh() Dumps the memory content to file.

get_data() Enables control over returned values of uninitialized addresses.

1.8.9.1 readmemh()

Syntax
readmemh(file_name : string, start_addr : vr_ad_addr_t, end_addr : vr_ad_addr_t,
file_start_addr : vr_ad_addr_t, file_end_addr : vr_ad_addr_t)

Parameters

file_name Name of file to read.

start_addr Data read from file will be written to memory starting from this address.
Typically, the start address is 0.

end_addr Data read from file will be written up to this address.

1-86 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_mem

file_start_addr File address to start reading from.

file_end_addr File address to read up to.

Description
This method loads values from a file into the memory. It is equivalent to the readmemh Verilog task or
VHDL procedure. The format of the file must be according to the standard supported by Verilog or
VHDL. In general, it will have the following structure:

@memory_address data1 data2 data3 …

The data file might look as follows:

@00 00 01 02 03 04 05 06 07
@08 08 09 0a 0b 0c 0d 0e 0f

Example
extend ex_c_bus_env {
run() is also {
mem.readmemh("data_file.txt",0,1000,0,1000);
};
};

1.8.9.2 dumpmemh()

Syntax
dumpmemh(file_name : string, start_addr : vr_ad_addr_t, end_addr : vr_ad_addr_t)

Parameters

file_name Name of file to write.

start_addr Data will be written to file starting from this memory address.

end_addr Data will be written to file up to this address.

Register and Memory Package Version 2.0 1-87


The Register and Memory Package
vr_ad_mem

Description
This method dumps the memory content to file. It is equivalent to the dumpmemh Verilog task or VHDL
procedure. The format of the file must be according to the standard supported by Verilog or VHDL (see
readmemh() on page 1-86).

Example
extend ex_c_bus_env {
finalize() is also {
mem.dumpmemh("data_file.txt",0,100);
};
};

1.8.9.3 get_data()

Syntax
get_data(addr :vr_ad_addr_t, size : vr_ad_addr_t): list of byte

Parameters

addr Address of the uninitialized area.

size Number of bytes that should be filled.

Description
This method is called each time an uninitialized area is read in the memory. By default, the returned data
is determined according to the policy in read_default_value. The size of the returned data is according
to the parameter size. If you need a different behavior, you can override this method and implement your
own logic. If you override this method, you must do it only under a specific memory subtype.

Example
extend EX_MEM vr_ad_mem {
get_data(addr : vr_ad_addr_t, size : uint) : list of byte is only {
result.resize(size,TRUE,0,TRUE);
for each (b) in result {
b = addr + index;
};
};
};

1-88 Version 2.0 Register and Memory Package


The Register and Memory Package
vr_ad_mem

The following tables describe the fields and methods of vr_ad_mem.

• “vr_ad_mem Fields” on page 89


• “vr_ad_mem Methods” on page 89
Table 1-23 vr_ad_mem Fields

Field Description

addressing_width_in_bytes: uint Width of each address entry in bytes. See “Customizing


Addressing Width” on page 1-44

backdoor_path: string HDL path for backdoor access

has_checks: bool Controls whether to have automatic compare checks.


Default is TRUE

kind: vr_ad_mem_kind Memory kind

read_default_value: [ZERO, Controls whether to return 0 (zero) or a generated data when


RANDOM] reading from an uninitialized address

size: vr_ad_addr_t Number of addresses occupied by the memory. By default,


the size is 0

Table 1-24 vr_ad_mem Methods

Method Description

get_data(addr : vr_ad_addr_t, size : Hook method, called whenever an uninitialized area is read
uint) so that you can provide data

write_backdoor(offset : Backdoor write to HDL memory


vr_ad_addr_t, data : list of byte)

read_backdoor(offset : Backdoor read from HDL memory


vr_ad_addr_t, len : uint) : list of byte

dumpmemh(file_name : string, Dumps the content of the memory from start_addr to


start_addr : vr_ad_addr_t, end_addr using hex formatting
end_addr : vr_ad_addr_t)

dumpmemb(file_name : string, Dumps the content of the memory from start_addr to


start_addr : vr_ad_addr_t, end_addr using binary formatting
end_addr : vr_ad_addr_t)

Register and Memory Package Version 2.0 1-89


The Register and Memory Package
vr_ad_sequence_driver

Table 1-24 vr_ad_mem Methods (continued)

Method Description

readmemh(file_name : string, Read the content of a hex-format file into the memory
file_type : string,
start_addr : vr_ad_addr_t,
end_addr : vr_ad_addr_t,
file_start_addr : vr_ad_addr_t,
file_end_addr : vr_ad_addr_t)

readmemb(file_name : string, Read the content of a binary-format file into the memory
file_type : string,
start_addr : vr_ad_addr_t,
end_addr : vr_ad_addr_t,
file_start_addr : vr_ad_addr_t,
file_end_addr : vr_ad_addr_t)

1.8.10 vr_ad_sequence_driver
The RSD is a dedicated sequence driver for register and memory operations.

1.8.10.1 Fields and Methods of vr_ad_sequence_driver


• “vr_ad_sequence_driver Fields” on page 90
• “vr_ad_sequence_driver Methods” on page 91
Table 1-25 vr_ad_sequence_driver Fields

Field Description

addr_map : vr_ad_map Reference to the address map

default_bfm_sd : Reference to a sequence driver that will be used for the


any_sequence_driver register accesses

bd_write_to_addr_map : bool Controls whether the RSD updates the e model upon
backdoor access

bd_read_from_addr_map : bool Controls whether RSD reads from the e model on backdoor
access

1-90 Version 2.0 Register and Memory Package


The Register and Memory Package
Address Management (Sets)

Table 1-26 vr_ad_sequence_driver Methods

Method Description

add_space(space : vr_ad_group, Adds an address space to the RSD. To be used when you
name : vr_ad_space_kind) have multiple address spaces (MEMORY, IO, CONFIG) on
the bus

1.9 Address Management (Sets)


The address map (vr_ad_map) provides address management functionality. It lets you name a set of
addresses and then allocate (generate addresses) from that group.

For example, assume that you have a slave DUT that responds to several inconsecutive addresses as
follows [0x0..0x500, 0x2000..0x3000, 0x3500..0x7000]. To randomly access the slave DUT, you would
want to generate random areas of various sizes inside the slave DUT address space. A possible request
might be to generate a 50 byte area but not beyond address 0x6000. The address map lets you define a
set of slave DUT addresses and then allocate random regions in it.

Figure 1-1 Address Management Model Example

0xffff 0x0

slave0_set slave0 slave0 slave0

To define an address set:

1. Add a field of type vr_ad_set to your address map.

2. Use the add_segment() method to initialize the new field with the desired regions.

For example, you could add the field slave0_set to your address map and then initialize it with addresses
[0x0..0x500, 0x2000..0x3000, 0x3500..0x7000] as follows:
extend MY_MAP vr_ad_map { // Add slave0_set to the address map
slave0_set : vr_ad_set;

post_generate() is also { // Initialize slave0_set


add_segment(slave0_set,0x0,0x500);
add_segment(slave0_set,0x2000,0x3000);
add_segment(slave0_set,0x3500,0x7000);
};
};

Once you define your set, you can allocate random regions in it.

Register and Memory Package Version 2.0 1-91


The Register and Memory Package
Address Management (Sets)

To allocate random regions in an address set:


• Use the method alloc_from_set().
For example, you could randomly allocate a region of 10 to 50 bytes inside the address range
[0..0x6000] as follows:
extend MAIN vr_ad_sequence {
body() @driver.clock is only {
// The parameters of alloc_from_set() are:
// Set field, min address, max address, min size,
// max size, alignment
var allocated_region : vr_ad_set =
map.alloc_from_set(map.slave0_set,0,0x1000,10,50,2);
var alloc_addr : vr_ad_addr_t =
allocated_regions.get_address();
};
};

Allocation removes the allocated region from the set, making it unavailable for subsequent allocations.
If, for example, alloc_from_set() allocated a 40 byte region [0x52..0x91], then:
slave0_set before allocation: [0 .. 0x500, 0x2000..0x3000,
0x3500..0x7000]
slave0_set after allocation : [0..0x51, 0x92..0x500, 0x2000..0x3000,
0x3500..0x7000]

To deallocate an allocated region in an address set:


• Use the method dealloc_to_set().
For example, you could deallocate the allocated region back to slave0_set as follows:
extend MAIN vr_ad_sequence {
body() @driver.clock is only {
var allocated_set :=
map.alloc_from_set(map.slave0_set,0,0x500,10,50,1);
// ...
// Deallocate the set
map.deallocate_to_set(map.slave0_set, allocated_set);
};
};

Note Address maps use predefined sets to allocate addresses for the addressable items. Each
time you add a register file to an address map (with add_with_offset() or
add_to_addr_map()), the address map allocates a region from the free_addrs set and adds a
region to the occupied_addrs set:

1-92 Version 2.0 Register and Memory Package


The Register and Memory Package
Address Management (Sets)

extend vr_ad_map {
free_addrs : vr_ad_set;
occupied_addrs : vr_ad_set;
};

Table 1-27 describes the main address set operations.

Table 1-27 Main Address Set Operations

Method Operation

add_segment() Initializes a set and adds the specified region to it

alloc_from_set() Allocates a region in a set

dealloc_to_set() Deallocates a set allocated by the method alloc_from_set()

lock_item() Locks an addressable item

release_item() Releases an addressable item locked by lock_item()

For a full list of the memory-management methods, see “Memory-Management Methods” on page 1-97.

1.9.1 add_segment()

Syntax
add_segment(set: vr_ad_set, min_addr: vr_ad_addr_t, max_addr: vr_ad_addr_t)

Parameters

set Name of the set that receives the region

min_addr Lower bound of the region address

max_addr Upper bound of the region address

Description
This method initializes a set and adds the specified region to it. You can add several segments to a set. If
you add contiguous segments, they are automatically combined into one segment in the set.

Register and Memory Package Version 2.0 1-93


The Register and Memory Package
Address Management (Sets)

Example
extend EX_MAP vr_ad_map {
slave0_set : vr_ad_set;
post_generate() is also {
add_segment(slave0_set,0x0,0x150);
add_segment(slave0_set,0x220,0x350);
};
};

1.9.2 alloc_from_set()

Syntax
alloc_from_set(set: vr_ad_set, min_addr: vr_ad_addr_t, max_addr: vr_ad_addr_t, min_size:
vr_ad_addr_t, max_size: vr_ad_addr_t, alignment: uint): vr_ad_set

Parameters

set Set to allocate from

min_addr Lower bound of the range to allocate from

max_addr Upper bound of the range to allocate from

min_size Lower bound of the size of the region

max_size Upper bound of the size of the region

alignment Alignment of the allocated region

Description
This method allocates a region in a set. The allocation is done randomly between the specified range of
min_addr and max_addr. The size of the region is also randomly generated between min_size and
max_size. The returned value is a new set created from the allocated region. You can get the region base
address and size by the methods vr_ad_set.get_address() and vr_ad_set.get_size(). To allocate the
whole address space (the range 0x0 to 0xffffffff, by default definitions), set min_size and max_size to
zero.

Example
extend MAIN vr_ad_sequence {

1-94 Version 2.0 Register and Memory Package


The Register and Memory Package
Address Management (Sets)

body() @driver.clock is only {


// Allocate 10 - 50 bytes between addresses 0 - 0x100 using
// alignment 2
var allocated_set : vr_ad_set =
map.alloc_from_set(map.slave0_set,0,0x100,10,50,2);
var allocated_addr : vr_ad_addr_t = allocated_set.get_address();
};
};

1.9.3 dealloc_to_set()

Syntax
dealloc_to_set(dest_set: vr_ad_set, alloc_set: vr_ad_set)

Parameters

dest_set Destination set for the deallocated region

alloc_set Set to be deallocated

Description
This method deallocates a set that was previously allocated by the method alloc_from_set().

Example
extend MAIN vr_ad_sequence {
body() @driver.clock is only {
var allocated_set :=
map.alloc_from_set(map.slave0_set,0,0x1000,10,50,2);
// Do something
map.deallocate_to_set(map.slave0_set, allocated_set);
};
};

1.9.4 lock_item()

Syntax
lock_item(ad_item: vr_ad_base): bool

Register and Memory Package Version 2.0 1-95


The Register and Memory Package
Address Management (Sets)

Parameters

ad_item Addressable item (instantiated in the address map) to be locked

Description
When you have a sequence that needs exclusive access to a register or a register file, you do not want
other sequences to interfere as long as the sequence is not finished. The address map contains a
predefined set for that purpose. The method lock_item() removes the relevant addresses from that
predefined set, preventing other sequences from locking the same addresses.

Example
extend MAIN vr_ad_sequence {
body() @driver.clock is only {
var my_reg = driver.addr_map.get_reg_by_address(0x100);
var item_is_locked = lock_item(my_reg);
if item_is_locked {
// Do something
};
};
};

1.9.5 release_item()

Syntax
release_item(ad_item: vr_ad_base)

Parameters

ad_item Addressable item to be released

Description
This method releases an addressable item that was previously locked by lock_item().

Example
extend MAIN vr_ad_sequence {
body() @driver.clock is only {

1-96 Version 2.0 Register and Memory Package


The Register and Memory Package
Memory-Management Methods

var my_reg = driver.addr_map.get_reg_by_address(0x100);


var item_is_locked = lock_item(my_reg);
if item_is_locked {
// Do something
release_item(my_reg);
};
};

1.9.6 Memory-Management Methods


• “vr_ad_map Memory-Management Methods” on page 97
• “vr_ad_set Methods” on page 98
Table 1-28 vr_ad_map Memory-Management Methods

Method Description

add_segment(set: vr_ad_set, min_addr: vr_ad_addr_t, Adds address range into a set


max_addr: vr_ad_addr_t)

add_to_addr_map(addr: vr_ad_addr_t, ad_item: Allocates addresses for an addressable


vr_ad_base, alignment: uint): vr_ad_addr_t item and adds the item to the address
map

add_unmapped_item(reg_file: vr_ad_reg_file) Adds unmapped register file to the


address map

alloc_from_set(set: vr_ad_set, min_addr: vr_ad_addr_t, Allocates addresses from a set


max_addr: vr_ad_addr_t, min_size: vr_ad_addr_t,
max_size: vr_ad_addr_t, alignment: uint): vr_ad_set

dealloc_addr_to_set(set: vr_ad_set, min_addr: Deallocates addresses into a set


vr_ad_addr_t, max_addr: vr_ad_addr_t)

dealloc_to_set(set1: vr_ad_set, set2: vr_ad_set) Deallocates the given set

intersect(set1: vr_ad_set, set2: vr_ad_set): vr_ad_set Returns the intersection set

is_in_set(set: vr_ad_set, addr: vr_ad_addr_t): bool Returns whether the address is in the set

lock_item(item: vr_ad_base): bool Locks an addressable item, preventing


other sequences from using it

release_item(item: vr_ad_base) Releases an addressable item

set_alloc_mode(set: vr_ad_set, mode: strategy_type) Can be random, first_fit, or best_fit

Register and Memory Package Version 2.0 1-97


The Register and Memory Package
Registers Visualization

Table 1-28 vr_ad_map Memory-Management Methods (continued)

Method Description

subtract(set1: vr_ad_set, set2: vr_ad_set): vr_ad_set Returns the subtraction set

union(set1: vr_ad_set, set2: vr_ad_set): vr_ad_set Returns the union set

Table 1-29 vr_ad_set Methods

Method Description

get_address() Returns the first address in the set

get_size() Returns the size of the set

set_policy(policy : vr_ad_set_policy_t) Sets the allocation policy [RANDOM,


BEST_FIT, FIRST_FIT]

segments_to_list() Returns a list of paired addresses. Each


pair contains the start address and end
address of a segment in the set

To demonstrate how sets are used to manage the address space:


• Run the vr_ad_space_management test.
specview –p "load vr_ad/examples/vr_ad_space_management;test"

For an example of AHB eVC sequences that use sets, see vr_ad/examples/vr_ad_ahb_sets.e.

1.10 Registers Visualization


The register and memory package provides graphical representations of your address map and register
files.

To access the registers visualization:


• At the Specman> prompt in Specview, issue the show map -win command.
Or:

• On the User menu of Specview, choose Show Maps.


A VT window showing the All Address Maps page opens. From that page, you can navigate to all
other visualization pages.

1-98 Version 2.0 Register and Memory Package


The Register and Memory Package
All Address Maps Page

This section explains the various address map visualization pages:

• “All Address Maps Page” on page 1-99 Table with all of the address maps
• “Top-Level Address Map Page” on page 1-99 Top-level content of the address map
• “Detailed Address Map Page” on page 1-100 Table with the full content of the address map
• “Register Files Page” on page 1-101 All register files related to the address map
• “Address Sets Page” on page 1-102 All memory sets related to the address map
• “Register File Page” on page 1-102 Content of the register file in stripes
• “Stripe Chart Page” on page 1-103 Stripe chart of the RSD sequences

1.10.1 All Address Maps Page


This page lists all address maps instantiated in the environment.

The table contains four columns:

Index Serial number


Map Hyperlink to the data browser
Top-Level Button that opens the Top-Level Address Map Page
Detailed Button that opens the Detailed Address Map Page

Figure 1-2 All Maps Page

1.10.2 Top-Level Address Map Page


The top-level address map page lists the highest level of hierarchy of the address map.

Register and Memory Package Version 2.0 1-99


The Register and Memory Package
Detailed Address Map Page

The table contains two columns:

Address Absolute address of the item


Item Visualization of the item

Figure 1-3 Top-Level Address Map Page

1.10.3 Detailed Address Map Page


The address map page displays a table of all addressable items (registers, register files, and memory
banks) of the selected address map.

The table contains five columns:

Index Serial number


Address Absolute address of the item
Item Hyperlink to the item
Value For registers, contains the value of the register
Stripe Chart Opens a page with the content of the item shown as a stripe chart.

In case of hierarchical addressable items (for example, a register file containing a register or another
register file), all items are displayed.

1-100 Version 2.0 Register and Memory Package


The Register and Memory Package
Register Files Page

Figure 1-4 Address Map Page

1.10.4 Register Files Page


The Register Files page displays a table of all register files related to the address map. This list contains
mapped and unmapped register files. The columns are the same as in the address map page.

Figure 1-5 Register Files Page

Register and Memory Package Version 2.0 1-101


The Register and Memory Package
Address Sets Page

1.10.5 Address Sets Page


The Address Sets page shows all memory sets instantiated under the address map. The table contains
two columns:

Name Name of the field of the set instance


Content List of all segments in the set
(For each segment, the start address and end address are printed)

Figure 1-6 Address Sets Page

1.10.6 Register File Page


The Register File page displays the content of the register file in a stripe chart view.

1-102 Version 2.0 Register and Memory Package


The Register and Memory Package
Stripe Chart Page

Figure 1-7 Register File Page

1.10.7 Stripe Chart Page


The Seq button on the toolbar of address map pages opens a stripe chart window for the corresponding
RSD sequences. The Stripe Chart page shows all register sequences created during the simulation.

Register and Memory Package Version 2.0 1-103


The Register and Memory Package

Figure 1-8 Stripe Chart Page

1.11 Register and Memory Commands


The register and memory package supports the following commands:

• show map Displays the address map, register files and registers
• trace ad alloc Initiates tracing of memory allocation operations

1.11.1 show map


The show map command produces address map reports.

1-104 Version 2.0 Register and Memory Package


The Register and Memory Package

Syntax

sh[ow] map [map-index] [-win]

Usage

Four variations of the command are provided:

show map Shows all address maps in the environment.


show map -win Shows all address maps in the environment in a VT window.
show map map-index Produces a report for the specified address map. The index is taken
from the show map command.
show map map-index -win Opens the address map report in a VT window.

1.11.2 trace ad alloc


The trace ad alloc command turns on the trace messages from address allocation and deallocation.

Syntax

trace ad al[loc]

Usage

The following vr_ad_map methods produce trace messages after the trace command is issued:
• alloc_from_set()
• dealloc_to_set()
• dealloc_addr_to_set()

Register and Memory Package Version 2.0 1-105


The Register and Memory Package

1-106 Version 2.0 Register and Memory Package


Index

A registers, access 1-37


BFM sequence driver
access integrating the register sequence driver 1-18
backdoor 1-39
add_to_addr_map() 1-80
add_unmapped_item() 1-81
C
add_with_offset() 1-75, 1-79 commands 1-104
address management model 1-91 compare_and_update() 1-70
address management, modeling 1-91 comparison, disabling for registers 1-47
address map 1-78 compilation 1-2
fields, register-related 1-84 conventions, naming 1-2
instantiating 1-15 types 1-59
methods, register-related 1-84 coverage 1-33
multiple on the bus, accessing 1-46 definitions, adding 1-35
register files, adding 1-15 definitions, modifying 1-35
updating 1-39 of fields, defining 1-14
Address Map page 1-99, 1-100, 1-101 register fields 1-34
Address Sets page 1-102 sampling, customizing 1-36
addressing width, customizing 1-44
All Address Maps page 1-99 D
All Maps page 1-99
architecture, eRM 1-7 data structure, register 1-61
data structures 1-59
def_reg macro
B defining registers with 1-9
backdoor Detailed Address Map page 1-100
access 1-39 deterministic configuration sequences, creating
defaults, overriding 1-38 1-25
operation 1-36 dumpmemh 1-87
operation, enabling 1-36

Register and Memory Package Version 2.0 Index-1


Index

E L
end of test 1-45 layering, register sequence drivers 1-16
eRM architecture 1-7
ex_c_bus environment 1-3 M
macros
F def_reg
features, main, package 1-2 defining registers with 1-9
fetch() 1-82 read_reg 1-23, 1-49
fetch_and_compare() 1-83 reg_def 1-10
fields reg_list 1-13
coverage, defining 1-14 write_reg 1-23, 1-49
order, registers 1-11, 1-43 main features, package 1-2
order, registers, changing 1-43 map, address 1-78
register instantiating 1-15
modifying 1-26 register files, adding 1-15
vr_ad_map 1-84 updating 1-39
vr_ad_node 1-75 mem_def 1-55
vr_ad_operation 1-22 memory 1-48
vr_ad_reg 1-72 addresses, uninitialized 1-52
vr_ad_reg_file 1-76 backdoor access 1-53
vr_ad_reg_static_info 1-73 instantiating 1-48
vr_ad_sequence 1-23, 1-41 objects 1-54
accessing in memory 1-57
G connecting to memory 1-55
creating 1-55
get_data 1-88 objects, accessing in memory
methods 1-58
H reading from file 1-51
hierarchy, types 1-60 returned data of uninitialized addresses,
controlling 1-52
side effects 1-53
I sparse memory 1-48
indirect registers updating 1-50
access handling 1-42 writing to file 1-51
addressing 1-39 memory model 1-1
addressing model 1-39 message verbosity, controlling 1-45
driving 1-40 methods
identifying 1-42 add_to_addr_map() 1-80
instances, register, defining 1-11 add_unmapped_item() 1-81
add_with_offset() 1-75, 1-79
compare_and_update() 1-70
fetch() 1-82

Index-2 Register and Memory Package


Index

fetch_and_compare() 1-83 read_reg_val() 1-63


post_access() 1-71 readmemh 1-86
read_reg_val() 1-63 reg_def macro 1-10
set_read_mask() 1-67 reg_list macro 1-13
set_static_info() 1-65, 1-66, 1-67, 1-68 Register File page 1-102
update() 1-69, 1-81 register files 1-74
vr_ad_map 1-84, 1-89, 1-91, 1-97 adding to address map 1-15
vr_ad_reg 1-56, 1-58, 1-72 defining 1-9
vr_ad_reg_file 1-77 entire, accessing 1-30
vr_ad_set 1-98 instantiating 1-14
write_reg_rawval() 1-64 mirroring 1-16
write_reg_val() 1-62 nodes 1-74
mirroring Register Files page 1-101, 1-103
register files 1-16 register instances, defining 1-11
registers 1-13 register model
model, address management 1-91 creating 1-7
model, registers integrating 1-7, 1-17
creating 1-7 monitor for updating 1-20
integrating 1-7, 1-17 updating, with monitor 1-20
modeling address management (sets) 1-91 register package
monitor, updating register model with 1-20 main features 1-2
register sequence driver
N instantiating 1-15
integrating with BFM sequence driver 1-18
naming conventions 1-2 register type, defining 1-12
types 1-59 registers 1-1
nodes, register files 1-74 address, defining 1-8
attribute structs 1-60
O backdoor access 1-37
order, register fields 1-11, 1-43 data structure 1-61
order, register fields, changing 1-43 data width, defining 1-8
overview 1-3 defining with def_reg macro 1-9
end of test 1-45
eRM architecture, in 1-7
P ex_c_bus environment, in 1-3
package, register field order 1-11, 1-43
main features 1-2 field order, changing 1-43
post_access() 1-71 fields, modifying 1-26
indirect
R access handling 1-42
addressing 1-39
random registers, accessing 1-28 addressing model 1-39
read_mem_obj 1-57 driving 1-40
read_reg macro 1-23, 1-49
Register and Memory Package Index-3
Index

identifying 1-42 types


layering, sequence driver 1-16 hierarchy 1-60
mirroring 1-13 naming conventions 1-59
model, creating 1-7
model, integrating 1-7, 1-17 U
random, accessing 1-28
sequence driver layering 1-16 update() 1-69, 1-81
sequences 1-45 updating, register model with monitor 1-20
using 1-20
writing to specific instance of register type V
1-26 verbosity, message, controlling 1-45
RSD visualization 1-98, 1-99, 1-100, 1-101, 1-102
fields, register-related 1-90 Address Map page 1-99, 1-100, 1-101
instantiating 1-15 Address Sets page 1-102
integrating with BFM SD 1-18 All Address Maps page 1-99
layering 1-16 All Maps page 1-99
methods, register-related 1-90 Detailed Address Map page 1-100
Register File page 1-102
S Register Files page 1-101, 1-103
sequence driver Sequences page 1-104
BFM, integrating with register sequence Stripe Chart page 1-103
driver 1-18 Top-Level Address Map page 1-99
register vr_ad_map 1-78
instantiating 1-15 fields 1-84
integrating with BFM sequence driver fields, register-related 1-84
1-18 methods 1-84, 1-89, 1-91
sequences methods 1-97
configuration, deterministic, creating 1-25 methods, register-related 1-84
register 1-45 vr_ad_node 1-74
Sequences page 1-104 fields 1-75
set_compare_mask() 1-47 vr_ad_operation 1-61
set_read_mask() 1-67 fields 1-22
set_static_info() 1-65, 1-66, 1-67, 1-68 vr_ad_reg 1-61
side effects, implementing 1-32 fields 1-72
sparse memory methods 1-56, 1-58, 1-72
See memory vr_ad_reg_file 1-74
Stripe Chart page 1-103 fields 1-76
structs, register attribute 1-60 methods 1-77
vr_ad_reg_static_info 1-73
fields 1-73
T vr_ad_sequence
Top-Level Address Map page 1-99 fields 1-23, 1-41
type, register, defining 1-12 vr_ad_sequence_driver 1-90

Index-4 Register and Memory Package


Index

fields, register-related 1-90


methods, register-related 1-90
vr_ad_set
methods 1-98

W
width, addressing, customizing 1-44
write_mem_obj 1-57
write_reg macro 1-23, 1-49
write_reg_rawval() 1-64
write_reg_val() 1-62
writing to specific instance of register type 1-26

Register and Memory Package Index-5

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy