uvm_object. The uvm_event class is directly derived from the uvm_object class. uvm_object

 
 The uvm_event class is directly derived from the uvm_object classuvm_object 02

UVM has a rich reporting facility. 04 Packed and Unpacked arrays 01. A grandparent class of uvm_sequence_item is uvm_transaction, which contains the following field definitions: class uvm_transaction extends uvm_object; const uvm_event_pool events = new; uvm_event begin_event; uvm_event end_event; //. You need to create a uvm_object temp variable, then do an explicit dynamic cast, e. uvm config db set method void uvm_config_db#(type T = int)::set(uvm_component cntxt, string inst_name, string field_name, T value); Where, T is the type of element being configured. After the utility macro are the field automation macros in the form ‘uvm_field_*(data member, flag). `uvm_field_utils_end. Only classes derived from uvm_component have knowledge of their parentage. This class will also need to be able to get information from the config_db using hierarchical paths, and plain old uvm_objects don't have hierarchy. You can either have a drive_item task in the driver, or you can call a. These macros are called by the corresponding uvm_*_utils macros, so you may only use them if you do. svh compiler cannot resove monitor as it doesn't know that type. Requirements. A parent creates a child, and the uvm_component represents a hierarchal family tree in a database. The utility macros help to register each object with the factory. The important thing to remember is that each entry needs a unique field name or label (if the global scope is being used), or the path needs to1 Answer. It allows for generic containers of objects to be created, similar to a void pointer in the C programming language. The UVMObject class is the base class for all UVM data and hierarchical. This object must be factory-enabled. It also becomes easier to connect to design regardless of the number of ports it has since that information is encapsulated in an interface. How do we ensure that this Configuration class can easily be propagated across the testbench environment? In UVM, objects are often instantiated through the factory infrastructure. Sorted by: 1. The first kind of queues store the handles to the uvm_resource objects that have the common field_name. uvm_comparer is the standalone class used to set a policy for doing comparisons and determines how miscompares are counted. Bases: object. virtual function void print_object (string name, uvm_object value, byte scope_separator = ” . Strictly speaking, you can define the do_print without using the uvm_printer, but if you do so, you are not able to. Factory is a centralized location to make calls from look-up tables for creation of any transaction types. We would like to show you a description here but the site won’t allow us. Accellera believes standards are an important ingredient to foster innovation and continues to encourage industry innovation based on its standards. Object and component types are registered with the factory using lightweight proxies to the actual objects and components being created. uvm_object is basically the main class. Abstract- SystemVerilog provides several mechanisms for layering constraints in an object. The UVM Test typically performs three main functions: Instantiates the top-level environment, configures the environment (via configuration objects, factory overrides or the configuration database), and applies stimulus by. Building UVM Verification Environment from Scratch. March 24, 2021. There are four basic reporting functions that can be used with different verbosity levels. path","label",value) (Adding other objects into the uvm_config_db is just as straightforward as adding a virtual interface. Inside a uvm_env class, I try to create an array of another uvm_env class. Unfortunately, SystemVerilog does not provide a good way to saveThere are two important aspects to pay attention to here: Use the `uvm_do_callbacks macro to call the appropriate function from our base callback class ; Use the `uvm_register_cb macro to register the callback class (acme_callback_addr_width) with the given object type (acme_env_config); Step #4: Define custom callback functions. A whole new worldThis modelsim seems to only have compiled libraries for device support primitives. 1. They are distinct objects. The uvm_object class is the base class for all UVM data and hierarchical classes. For more efficient and more flexible implementation, we can use user definable do_*() hooks. uvm_event is used to synchronize the two processes. Before moving to uvm_sequence_item will look into uvm_object concepts required to write uvm_sequence_item, The uvm_object has a number of virtual methods that are used to implement common data object functions (copy, clone, compare, print, transaction, and recording) and these should be implemented to make the sequence_item more general purpose. This guide is a way to apply the UVM 1. Objects are dynamic, so implicitly the question you are asking is invalid. The uvm_object or sequence overriding is similar to the uvm_component overriding factory mechanism that returns the derived object handle using a base class handle. endclass This means that our long list of assignments that the copy expands to would also contain: copy. Gets the data, if any, provided by the last call to trigger. このページの最後に載せておきます。. sv and the many svh files for the class files (reg, tlm, macros, drivers. This article explains how to use a verbosity threshold to filter messages. The function that is actually called depends on the context where the macro is used. The `name` input is used for purposes of storing and printing a miscompare. 1 to create reusable and portable testbenches. The utility macro `uvm_object_utils registers this class with the factory, which we will discuss later, and allows access to the create method which is needed for cloning. 1. The uvm_object class is the base class for all UVM data and hierarchical classes. It is extended from its parent class uvm_resource_dbMarch 24, 2021. The uvm_object provides methods like create, clone, copy, record, compare, print, etc. The uvm_object class is the base class for all UVM data and hierarchical classes. if you just declare the P2 as" My_Packet P2;" , the cast will work. 이때 아래의 그림과 같이 agent내부에서는 어떤 configuration이 uvm_config_db를 통하여 설정됨을 가정하여 get ()으로. uvm_object¶ class uvm. In order to have the resource automatically retrieved two things must happen: First, that resource has to be registered with the factory using the field automation macros. However, are they supported by UVM?When working with UVM, the phrase "you gotta use the factory!" gets drilled into our heads constantly. Follow edited Apr 23, 2014 at 8:00. method_call() is really method_call(. UVMには、さまざまなオートメーション機能が実装さ. 0 using simple producer/consumer examples. The most common UVM macros are: uvm_component_utils: registers a new class type when the class derives from the class uvm_component; uvm_object_utils: similar to uvm_component_utils, but the class is derived from the. Typically configuration classes and data objects are derived from this class and are passed to different testbench components during the course of a simulation. uvm_object_utils() is used to register a class as a UVM object, which is a generic container for data used in a UVM testbench. Classes deriving from uvm_object must implement the pure virtual methods such as create and get_type_name. macro: Can be used, but try to avoid if you are. virtual class uvm_component extends uvm_report_object; uvm_component class definition provides many functions and tasks that are used to find, build, connect, and configure. uvm config db set method void uvm_config_db#(type T = int)::set(uvm_component cntxt, string inst_name, string field_name, T value); Where, T is the type of element being configured. ; Once you convert your testbench from passing individual values to passing config objects, you can see the bigger picture, which is that a testbench is configured and built from the top down, guided by the configuration. Similarly uvm_object::compare() calls the __m_uvm_field_automation() with UVM_COMPARE. You are mixing up the terms parent and child with the principals of class inheritance. The packer determines how the packing. check my simple example on here on edaplaygroud. uvm_reg_sequence. We would like to show you a description here but the site won’t allow us. Read more: UVM Object [uvm_object] In my last post, I recommended that you give every SystemVerilog object either a unique ID or name. An uvm_component inherits from. Enjoy your verification journey!SystemVerilog functions have the same characteristics as the ones in Verilog. This proxy object is of uvm_component_registry class parameterized with the type of the initially desired component/object. That means the default value is going to be used in new(). In a previous article, copy, do_copy and use of automation macros to print were discussed. You can: Derive your object_a from uvm_report_object instead of uvm_object. class uvm. essentially take the current global id then increment the counter. The UVM methodology enables engineers to quickly develop powerful,. The reason being packet and packetD are type compatible, since packetD is an extension of packet. It attempts to mirror the design registers by creating a model in the verification testbench. Agent includes a UVM sequencer to manage stimulus flow, a UVM driver to apply stimulus to the DUT interface, and a UVM monitor to monitor the DUT interface. uvm_object has many common functions like print, copy and compare that are available to all its child classes and can be used out of the box if UVM automation macros are used inside the class definition. task body; i2c_packet pkt; pkt = i2c_packet::type_id::create("pkt"); pkt. There are three relevant uvm_report_error() function definitions in the UVM library: uvm_report_object. The reason why case 1 fail is that you "new" P2, which means the P2 is instantiated, so it is not only a handle. The create method internally makes a call to the factory to look up the requested type and then. OOP design patterns take reuse another step. The singleton instance of uvm_coreservice_t provides a common point for all central uvm services such as uvm_factory, uvm_report_server and so on. `uvm_do (Item/Seq) This macro takes seq_item or sequence as argument. e. “value” is the actual object handle shared through the uvm_config_db. The first three methods above take uvm_object_wrapper as their type argument (s). So, a data class derived from uvm_sequence_item or uvm_component will have access to the print() function as well. The monitor captures values on the DUT's input and output pin. Line 11-Line 15 Use the UVM functions to automatically implement functions such as copy(), compare(), print(), pack(), and so on. 2 Class Reference represents the foundation used to create the UVM 1. All the signals listed as the module ports belong to APB specification. comp", "db_rx_agent_cfg", rx_cfg);The factory makes it is possible to override the type of uvm component /object or instance of a uvm component/object in2 ways. The uvm_config_db class is the recommended way to access the resource database. 02. It makes sense to include print features in uvm_object so that all child classes will automatically gain access to those features. 1. uvm_object-based class declarations may contain one of the above forms of utility macros. It allows for generic containers of objects to be created, similar to a void pointer in the C programming language. Jun 20, 2014 at 15:13. TYPE’s constructor, if defined, must have default values on all it arguments. This is not a complete design since our purpose is simply to show how registers in this design can be read/written using a UVM register model. Register the callback class. uvm_factory. Typically configuration classes and data objects are derived from. This method calls uvm_event_base::wait_trigger followed by get_trigger_data. It is the base class for all UVM data and hierarchical classes. 2. The uvm_object_registry has static methods, which you call with the class::type_id::create () syntax. sv & uvm_pkg. Object Overriding; UVM Phases; UVM Objections; UVM Object. Divide the DB into smaller domains by grouping values into config objects. The UVM application programming interface (API) defines a standard for the creation, integration, and extension of UVM Verification Components (UVCs) and verification environments that scale from block to system. To avoid the overhead of creating an instance of every component and object that get registered, the factory holds lightweight wrappers, or proxies. {"payload":{"allShortcutsEnabled":false,"fileTree":{"distrib/src":{"items":[{"name":"base","path":"distrib/src/base","contentType":"directory"},{"name":"comps","path. 总结:在多进程IP中,寄存器模型 中参数uvm_object extension的使用可以极大的方便验证工程师的工作。. The print method is used to deep print UVM object class properties in a well-formatted manner. Improve this answer. To do this job easier, uvm has predefined macros. Using automation macros. uvm_config_dbに渡すパラメータタイプはuvm_object_wrapperになります。これはuvm_config_dbにtypeを登録する場合の型です。 第一引数は通常はthisです。 第二引数は対象となるシーケンサのUVMの階層名+フェーズ名になります。From the application point of view, UVM Factory facilitates an object of one type to be substituted with an object of derived type without having to change the structure of the Testbench or modify the Testbench code. 1 I see a lot of articles which talk about whether you should be using field macros. Intro. This concept is widely used in UVM, especially the uvm_config_db configuration database. so when you print the object right after its construction you both should be almost the same. uvm_component::set_inst_override (relative_inst_path, original_type_name, override_type_name) The fourth method is using the set_inst_override function of the uvm_component. The first step is to use macros to register all the class types with the factory. Step #1: Create a base callback class. For example, a uvm_registry base class could have provided the required infrastructure for creation and factory overrides. Using automation macros. events. Aside from registering a class with the factory, we've seen that the. The packer determines how the packing. UVM configuration provides. UVMFactory is used to create objects of type UVMComponent and UVMObject (and their derived user-defined types). 07 Flow Control 01. Class Hierarchy Class Definition See full list on chipverify. If you use the uvm_top. Using do_record. It is an abstract class with no data members or functions. . It also becomes easier to connect to design regardless of the number of ports it has since that information is encapsulated in an interface. uvm_pool allow us to store any type of data with a key as index, similar to an associative array. 1 Inheritance and Constraint Layering ¶ In our previous two posts in this series on Python as a verification language, we examined Python coroutines and using coroutines to create cocotb bus functional models. do_pack. This would have provided a better separation of concerns. The first kind of queues store the handles to the uvm_resource objects that have the common field_name. The uvm_subscriber is derived from uvm_component and adds up the analysis_export port in the class. answered Sep. What happens when both handles point to same object ? If we assign pkt to a new variable called pkt2, the new variable will also point to the contents in pkt. Unfortunately this wont work yet because we have to register seq_item as follows `uvm_object_param_utils(seq_item#(A)). KEY(int),. Every class item derived from uvm_object will have a printer instance within it. It is a standardized methodology for verifying digital designs and systems-on-chip (SoCs) in the semiconductor industry. trigger. 4) uvm_object required to define the uvm_object::creat() method. raise_objection (uvm_object obj = null, string description = ” “, int count = 1) Raises number of objections for corresponding object with default count = 1. pseudo code looks like this: class seq_item extends uvm_sequence_item; rand class_a a; rand class_b b; endclass// seq_item class class_a extends uvm_object; rand bit field_1; rand bit field_2; endclass//class_a class class_b. 3. UVM Factory is a standardized mechanism to create different objects. It looks like you have a compilation of uvm_pkg from a previous run that is conflicting with this run. Description. When set, metadata should be encoded as follows: For strings, pack an additional null byte after the string is packed. Share. gz. Uvm_components contains all methods the uvm_objects have. We would like to show you a description here but the site won’t allow us. By applying stimulus to the register model, the actual design registers will exhibit the changes applied by the stimulus. g. The register model can be used to read and write registers in the DUT, including signals connected to those registers. UVM 1. If no argument is specified (or an argument. Not sure how that is going to help. の間に挟んで使うマクロです。. One of the classes contains a handle for the other class. Tx t1, t2; t1 = new (); t1. get_trigger_data. It consists of all the basic methods, macros, identification fields in it. The print method is used to deep print UVM object class properties in a well-formatted manner. In a type override, a substitute component class type is created instead of an original component class in the testbench hierarchy. uvm_object. Extend that class and implement the virtual method. Main concepts of UVM (1) • Clear separation of test stimuli (sequences) and test bench –Sequences are treated as ‘transient objects’ and thus independent from the test bench construction and compositionHow to use the UVM configuration facility? Configuration values are set in the uvm_config_db class using the set() method and retrieved using the get() method. It allows for generic containers of objects to be created, similar to a void pointer in the C programming language. UVM TestBench to verify Memory Model. You can use the uvm_object_registry (T,S) or uvm_component_registry (T,S) registration macros. This method calls uvm_event_base::wait_trigger followed by get_trigger_data. The uvm_object class is the base class for all UVM data and hierarchical classes. zhang@amd. Two things: 1) You could extend mem_seq_item from "uvm_sequence_item" instead of "uvm_object". User classes derived directly from uvm_void inherit none of the UVM functionality, but such classes may be. It is an object that is used for instantiating other objects. 613. uvm_config_db#(TYPE)::set(this,"*. Pre-defined Verbosity Levels. UVM tutorial for beginners Introduction Introduction to UVM UVM TestBench TestBecnh Hierarchy and BlockDiagram UVM Sequence item Utility & Field Macros Methods with example Create Print Copy Clone Compare Pack UnPack UVM Sequence Sequence Methods Sequence Macros Sequence Example codes UVM Sequence control UVM. I did not register any class with the same name, unless the parent one which, I suppose, does not present any problem. The documentation only instructs on how to unzip the tar. This can be useful for peak and off-peak times. Policy classes are used to implement polymorphic operations that differ between built-in types and class-based types. After new'ing , it uses set_name() to assign the appropriate value to. The handle to the uvm_resource object is stored in two kinds of uvm_queues. The tutorial explains the UVM concepts, structure, coding style, and best practices with examples. 1. S. Then you can do: typedef uvm_object_registry# (abc_test_seq,`STR (`SEQ_NAME (abc))) type_id;. The following methods are also part of the uvm_objection class: clear(): Immediately clears the objection state. The uvm_object class is the base class for all UVM data and hierarchical classes. 1 Class Reference is a comprehensive document that describes the classes, methods, macros, and callbacks that constitute the UVM 1. Q&A for work. H. Using Callback. Blocks ¶. Tudor Timi Tudor Timi. event_object_h =. uvm_object The primary role of uvm_object class is to define a set of common utility functions like print, copy, compare and record which can be availed by any other class in a UVM testbench to save effort. As the name suggests, it keeps a track of the sequences that are registered with it, and calls them a number of times in a random fashion. Unlike the above three methods, this function takes three strings. 2) from Accellera. This class will also need to be able to get information from the config_db using hierarchical paths, and plain old uvm_objects don't have hierarchy. Include the class inside the testbench and instantiate an object. Add a comment. uvm_object::create method allocates a new object of the same type as this object and returns it via a base uvm_object handle. class my_driver. Block abstraction base class. We would like to show you a description here but the site won’t allow us. That is different from the strategy that you might choose in order to drive signals. 02. UVM stands for U niversal V erification M ethodology. UVM provides a transaction class that can be extended to create transaction objects that carry information between the DUT and the testbench. Please see Register Abstraction for how each property is packed. You do not have one. 02 Data Types 01. The uvm_comparer adds up policy for the comparison and counts the number of miscompares if any. 1 min read. print_topology() or factory. The constructor of uvm_component adds a uvm_component parent argument which is used to create. Its primary role is to define a set of methods for such common operations as create , copy, compare, print, and record . uvm_config_db# (rx_agent_cfg)::get (null, "uvm_test_top. 09. object queues and publishes a number of transfers equal to the total length of the burst size. These levels are nothing but integer enum values (the parentheses in the figure show the values). You can use wildcards in the scope strings, but limit them to the end of the string to help performance. This article explains how to use a verbosity threshold to filter messages. Connect and share knowledge within a single location that is structured and easy to search. A cleaner implementation would have been for uvm_component_registry to be its own class, that doesn’t extend uvm_object_wrapper, that instead creates an instance of a uvm_object_wrapper and registers it with the factory instead of itself. We remember the file and line number, and the calling context (the. There are two important parts to using the factory. 用途は、UVMの「オートメーション」機能を適用するために使います。. UVMObject (name: str) [source] ¶ Bases: sv_obj. See Usage section below for information on using uvm_component_registry. This makes them more flexible, and able to work on a range of data types instead of just a single one. UVM pre-defines six verbosity levels; UVM_NONE to UVM_DEBUG. The create method internally makes a call to the factory to look up the requested type and then. Intro. メンバの型によって、さまざまあります。. Bases: uvm. You're trying to assign a handle of base class type to a handle of derived class type, which isn't allowed in SV. Once unzipped, I see the source files with uvm. myagent. uvm_resource_db; uvm_config_db; Passing interface handle and two agent example; UVM testbench Top; UVM Test; UVM Environment; UVM Sequence Items; UVM Driver;The uvm_driver is parameterized to accept a class object of the type my_data and the driver is expected to unpack this class object and drive the signals appropriately to the DUT via the interface. The verification testbench will be developed in UVM and has the following block diagram: The sequence generates a random stream of input values that will be passed to the driver as a uvm_sequence_item. trigger. We are then calling the "set_finish_on_completion" method. For convenience, you can use the subtype, uvm_in_order_built_in_comparator # (T) for built-in types. Its primary role is to define a set of methods for such common operations as create, copy, compare, print, and record . These macros can appear anywhere in the declaration space of the class declaration of T and will associate the string S to the object type T. Without it, registration would require an instance of the object itself. The left-hand-side `lhs` and right-hand-side `rhs` objects are the two objects used for comparison. This is a message generated by vcs: Error- [ICTTFC] Incompatible complex type usage Incompatible. g. set_type_override_by_name ("base_sequence",`STR (`SEQ_NAME (abc))); In. 02. 02. A flat uvm_config_db with wildcard scopes and many entries can be a performance hog. Test program작성 및 script 작성. class uvm. Then,. UVMReportObject. uvm_objects have clone/do_copy virtual methods, that can be used to clone/ do a deep copy of an object. trace_mode(): Set or get the trace mode for the objection object. Let’s call the record in our jelly bean scoreboard. UVM uses the concept of a factory where all objects are registered with it so that it can return an object of the requested type when required. uvm_config_db::get () is used to fetch the value of the virtual interface and assign it to configuration object property. Is this achievable in UVM 1. base. Let's take an example of three sequences, all derived from the same base_sequence class, as we. do_pack. A uvm_queue is created for every unique field_name. When someone wants to implement object names, what they'll do is pass a "string name" in the constructor of every object, so when the object is. For objects, pack 4 bits prior to packing the object itself. To access a DUT signal in a UVM component or UVM object, you can use the UVM Register Abstraction Layer (RAL) to create a register model of the DUT’s design. For simple objects with no field macros, use `uvm_object_utils(TYPE) For simple. `uvm_do (Item/Seq) This macro takes seq_item or sequence as argument. In the UVM, there are mechanisms to automate the retrieval of data from the configuration database. There are different variations to this macro, just like `uvm_do_*. TYPE’s constructor, if defined, must have default values on all it arguments. id = 42; At this point you might be tempted to call the object “t1”. Also, uvm_pool is a singleton class , that explains why it has global access. UVM TestBench architecture. One step beyond. The important thing to remember is that each entry needs a unique field name or label (if the global scope is being used), or the path needs to 1 Answer. Constraints may be added via inheritance in a derived class. Constraints may be added via inheritance in a derived class. Using wait_for_grant(), send_request(), wait_for_item_done() etc b. Built in types (such as ints, bits, logic, and structs) can be compared using the default values for comp_type, convert, and pair_type. A cleaner way would be to use the sequence library provided by UVM as uvm_sequence_library. This command is going to call the ::type_id::create command from the tb_driver, which happens to be code largely inherited from other macros and classes. Writing user-defined callback, class user_defined_callback extends uvm_event_callback; --- endclass. For Design specification and Verification plan, refer to Memory Model. First, let's. The UVM object is a data structure used for testbench configuration and it is the base class available for component and sequence branch. Within a non-static class method, randomize() and this. You always could use 'uvm_field_array_int and a pair of pack/unpack function that transforms the pixel info into an int (you would still have a byte of the int free) and the other way round. UVM uses the concept of a factory where all objects are registered with it so that it can return an object of the requested type when required. as you can see from your log that isnt the case for IUS. 03 Operators 01. Posted November 30, 2015. Pass config objects inside your testbench with OOP-style set_config() methods, instead of the confusing uvm_config_db. 2 Class Reference for information on the uvm_object_utils_begin, uvm_object_utils_end, uvm_field_*, and their associated macros. drop_objection (uvm_object obj = null, string description = ” “, int count = 1) Drops number of objections for corresponding object with default count = 1uvm_object is the main class in which common functions to print, copy, and compare two objects of the same class are defined. This can be useful for peak and off-peak times. 1. UVM REPORTING The uvm_report_object provides an interface to the UVM reporting facility. class my_driver. Improve this answer. 4 UVM Agent. The uvm_event class is directly derived from the uvm_object class. to drive the designated signals into DUT. Because phases are defined as callbacks, classes derived from uvm_component can perform useful work. These macros form a block in which `uvm_field_* macros can be placed. Share. class tx_item extends uvm_sequence_item;. It allows for generic containers of objects to be created, similar to a void pointer in the C programming language. When the factory is called upon to create an object. uvm_object is the one of the base classes from where almost all UVM classes are derived. But, virtual_sequence and virtual_sequencer do not require any virtual keyword. 2. Then you can do: typedef uvm_object_registry# (abc_test_seq,`STR (`SEQ_NAME (abc))) type_id;. In the do_print function, we merely list the variables we want to print using the functions of uvm_printer class (lines 3 to 8). The uvm_driver is parameterized to accept a class object of the type my_data and the driver is expected to unpack this class object and drive the signals appropriately to the DUT via the interface. The service class provides a static <::get> which returns an instance adhering to uvm_coreservice_t. It is an abstract class with no data members or functions. It may be helpful to model this sequence as a hierarchical sequence where the generation of SIZED and QTAGGED packets are defined as flat sequences (generating only transaction items). User classes derived directly from uvm_void inherit none of the UVM functionality, but. Pass config objects inside your testbench with OOP-style set_config() methods, instead of the confusing uvm_config_db. 2 uvm_object constructor. Using do_copy. uvm_object - Data structures for testbench configuration; uvm_transaction - Stimulus generation & analysis; The values of the arguments of new method are used to create an entry in a linked list which the UVM uses to locate uvm_components in a pseudo hierarchy, this list is used in the messaging and configuration mechanisms. Improve this answer. SystemVerilog allows you to create modules and classes that are parameterized. UVM TestBench to verify Memory Model. These Subtypes include uvm_printer, uvm_line_printer, uvm_tree_printer, uvm_table_printer. The uvm_config_db class provides a convenience interface on top of the uvm_resource_db to simplify the basic interface used for uvm_component instances. The user can simply apply a different. Say the object is "my_tb". Thus, it can save the simulation time and terminate it at an early state. e. UVM Factory Override. You need to create a uvm_object temp variable, then do an explicit dynamic cast, e. env. So UVM phases act as a synchronizing mechanism in the life cycle of a simulation. 05 Data Arrays 01. Using automation macros.