
Explore UVM fundamentals, build verification environments with the UVM library, and advance to the register abstraction layer in part three of this four-part series to verify complex designs.
Explore how to use multiple IDEs to execute UVM code, from cloud-based eda playground to questa Sim simulations and the vivado IDE.
Explore using EDA Playground to run UVM code, create testbench and design files, choose SystemVerilog and UVM 1.2 with ALDEC simulator, and share or save projects.
Learn to execute UVM code in Vivado 2019.2 or higher, with Artix-7 A701, Verilog simulation, and UVM library configuration using -L uvm and xsim elaborate options.
Learn to execute a UVM code in Questa Sim by creating a new SystemVerilog tb, saving and compiling, and running a simulation to display Hello World.
Explore the four UVM reporting macros and adjust verbosity to filter messages across components, hierarchies, and the testbench environment. Learn to override macro actions to control console output.
Explore UVM reporting mechanisms that communicate data to a console, including UVM info with a three-argument format and verbosity levels. Contrast warning, error, and fatal, with fatal stopping the simulation.
Explore how to send data to a console with the UVM info macro. Compare UVM info with display and learn essential UVM macro and package setup for test benches.
Declare data = 56 and print its value to the console in an initial block using UVM info and the s format F function with %d, without automation.
Learn how UVM verbosity levels control what prints to the console, from none to bug, using get and set report verbosity level on the default UVM top, with practical examples.
Explore how to manage verbosity in UVM with per-id controls, including set_report_verbosity_level and set_report_id_verbosity, and see uvm_info messages governed by drv1 and drv2.
Explore how to manage verbosity for individual components and entire environments in UVM by extending uvm_driver and uvm_environment, registering to a factory, and using set_report_verbosity_level or run options.
Adjust the verbosity of a whole hierarchy by using set_report_verbosity_level_hier in a uvm environment, applying uvm_high to all driver and monitor components.
Compare UVM reporting macros—info, warning, error, and fatal—highlighting their colors and default behaviors, with fatal stopping the simulation while warnings and errors may continue until a limit.
Learn to adjust UVM reporting severity by using set report severity override for a class and set report severity ID override for individual IDs, converting fatal events to errors.
Learn to modify macro actions in UVM by overriding sev actions with set_report_severity_action, combining actions like UVM_DISPLAY, UVM_NO_ACTION, and UVM_EXIT, and observing their effects on console output and simulation control.
Learn to control UVM error handling by setting a quit threshold with set_report_max_quit_count, causing do_die on reaching the limit while UVM_ERROR, UVM_WARNING, and UVM_FATAL show distinct default actions.
Open log.txt and obtain a file descriptor to store UVM log data. Configure set_report_default_file with the descriptor and use UVM_DISPLAY | UVM_LOG to write console messages to the log file.
Explore the base classes of a verification environment by examining UVM object and UVM component, and learn core methods, field macros, and do hooks, including inbuilt versus custom implementations.
Explore how UVM builds verification environments with static components, dynamic transactions, a UVM tree, and phases, using UVM objects and components to drive drivers, monitors, and scoreboards.
Learn the fundamental UVM objects: UVM transaction, UVM sequence item, and UVM sequence, for dynamic components, and the static UVM components: driver, sequencer, monitor, agent, scoreboard, environment, and test.
Learn the fundamental and dynamic UVM components, including transaction objects and sequences. Discover core methods such as print, copy, compare, pack, and unpack, plus field macros or do methods.
Learn to build a transaction class by extending UVM classes, master field macros and core methods of a UVM object, and work with do methods through practical examples.
Develop a base class to form a uvm environment, including a 4-bit data member, constructor, randomize usage, and displaying values in decimal within a testbench top using vcs.
Deriving from the UVM object, this lecture guides creating a UVM object class, registering with the factory, and using a constructor, a data member, and randomization in a testbench.
Register class variables to a factory using UVM field macros within UVM util begin and end, enabling automated data methods and optional printing.
Learn to change data display format with UVM printers (table, tree, or line) by passing printer instances, using field macros to register variables, and configuring radix for binary or decimal.
Learn to declare enum, real, and string fields with UVM_FIELD macros, register them via UVM_OBJECT_UTILS_BEGIN/END, and see a state_type enum, a real temp, and a string "UVM" in action.
Learn to use field macros (uvm_object_utils, uvm_field_int, uvm_field_object) to register parent and child classes, enabling printing and exploring build phase and create method in a uvm object testbench.
Explore static, dynamic, queue, and associative arrays in SystemVerilog UVM, using macros such as uvm_field_sarray, uvm_field_darray, uvm_field_queue, and uvm_field_aarray_int_int. Implement a test bench that allocates, fills, and prints array data.
Explore copy and clone in UVM, showing that copy requires a constructor on the target while clone does not, demonstrated with a 4-bit data member and randomization.
Explore shallow versus deep copy in UVM by comparing copy and clone methods, demonstrating how independent versus shared handles affect data across object instances.
Explore copy and clone methods in the UVM essentials, showing constructor-based shallow copies from s1 to s2 and deep copies via clone.
Learn how the UVM compare method checks if two objects have identical data, returning 1 when equal and 0 otherwise, using two instances, randomization, and a copy to force equality.
Use the create method to instantiate UVM objects, enabling factory-based type overriding. The lecture demonstrates F1 and F2 creation with type_id::create, path arguments, randomize, and print to verify object creation.
Learn the advantages of registering classes with the factory and using the create method to instantiate objects, and how set_type_override_by_type swaps first with first_modified in a transaction class.
Learn an alternate do_print implementation in UVM essentials that prints a, b, and c without the field macro and requires registering the class with the factory for override capabilities.
Explore convert2string to concatenate data members a, b, and c into a single line using sformatf, without a uvm printer object, and print with $display or uvm_info for debugging.
Learn how the do_copy method copies data from a rhs uvm object to the current object by casting to a temp and updating a and b.
Implement the do_compare method in UVM for field-by-field equality, using cast and temp access, and verify with two objects o1 and o2 via do_print/do_copy references.
Explore static components of a verification environment, including driver, monitor, scoreboard, agent, environment, and UVM tester, and learn how UVM trees aid debugging the entire verification code.
Explore how the UVM tree organizes the test bench, with UVM top as the root and leaves such as scoreboard, monitor, driver, and sequencer.
Extend a UVM component to create a class, register it to the factory, and implement build phase and run phase, using config DB and phases to manage verification environment.
Create a simple UVM tree with leaves A and B under subtree C, with the UVM root as the parent, then use build phase and run test to print topology.
Learn to create a UVM test top with the create method, attach it to the UVM root, and avoid deprecated manual build calls; rely on run test for top creation.
Explore how to share resources between classes using the UVM config db, focusing on the get and set methods, with fundamentals and a practical demonstration.
Demonstrate using the UVM config DB to share data between an environment and a test class with set and get operations, illustrating cross-class data access.
Build a UVM testbench with comp1 and comp2, using the config db, share data via data1 and data2, and print values in the build and run phases.
Demonstrate using the UVM config DB set and get methods to share an integer data value across classes, forming a path from instance name and key, yielding 256 in components.
Explore building and accessing UVM paths from the test top to environment, agent, and components using this keyword, get and set methods, and data concatenation. Resolve mismatched concatenations to avoid UVM errors and premature simulation finish.
Demonstrate providing access to all components in an agent with an asterisk, enabling component one and component two to access data via the set method in the UVM config DB.
Explore a minimal uvm verification using a 4-bit adder with a virtual Adder_if, accessed via the uvm config db, while the driver emits 10 random stimuli every 10 ns.
Explore how UVM phases manage simulation execution, distinguishing time-consuming from non-time-consuming phases and handling stimuli timing. Learn phase debugging and drain time to pause the simulation after an objection.
Explore the fundamentals of UVM phases, from configuring the verification environment to applying stimulus, connecting components, and collecting reports through sequential phases.
Classify phases into time-consuming and non-time-consuming categories, noting that timed phases use tasks with timing constructs while non-timed phases use functions and require overriding with super.
Learn how build_phase creates objects, connect phase handles connections in TLM to share data, end-of-elaboration adjusts hierarchy, and start-of-simulation configures the environment before applying stimulus.
Explore the run phase, which generates stimuli, applies them to the DUT, and collects responses, with pre-reset and post-reset phases, plus configure, main, and shutdown phases totaling 12.
The cleanup phase in UVM collects and reports data and checks whether coverage goals are achieved, completing the 20-phase UVM structure across construction, run, and cleanup.
Explore two uvm phase classifications: time-consuming phases (task methods, no super) and non-time-consuming phases (functions, with super), plus the construction, run, and cleanup phases and how to override them.
Override UVM phases by using functions for non-time consuming phases and tasks for time-consuming ones, calling super when needed, focusing on build, connect, end of elaboration, start of simulation, and run.
Explains how build_phase executes across multiple UVM components, highlighting a top-down order from test to environment to driver and monitor, while other phases run bottom-up.
Examine how the connect phase executes in UVM in a bottom-up sequence across driver, environment, and test class, contrasting it with the build phase's top-down flow.
In the execution of multiple instance phases, priority follows lexicographic path names (lowercase) in the build and connect phases; driver and monitor order shifts with path name changes.
Master how to use raise and drop objections to hold the simulator during time-consuming UVM phases, starting with reset, and coordinate delays across components and sequences.
Illustrates timing constructs in a UVM component using reset and main phases with objections to add delays, revealing reset 0–10 ns and main 10–110 ns before configure and shutdown.
Understand how time-consuming phases work across multiple components in a UVM environment, with driver and monitor reset and main phases delaying next phases until all components finish.
Set the timeout with the UVM root and uvm_top to define a simulation limit; if exceeded, a fatal error occurs, with an overridable default timeout.
Explore how drain time in UVM adds a 200 ns buffer to the main phase, with an example of applying set_drain_time to an individual component and observing post main phase.
Apply drain time across multiple components by synchronizing reset, main, and post main phases in a UVM verification environment, ensuring all components complete before the drain timer starts.
Enable UVM phase trace with +UVM_PHASE_TRACE to debug phase transitions from start to completion. Analyze sequencing of build, connect, and elaboration phases, and monitor start, schedule, skip, and done events.
Debug objections with UVM_OBJECTION_TRACE to analyze how components raise and drop objections. Track the objection count across reset and main phases to determine when the simulator stops.
Explore uvm tlm communication, including blocking and non-blocking, and put, get, transport, and analysis ports. See how sequencers send sequences to drivers and monitors feed scoreboards via an analysis bus.
Explore fundamentals of UVM essentials, including sequencer-driven test benches, drivers, interfaces, and DUT interactions, with transaction-level modeling and blocking, non-blocking put, get, and transport operations.
Understand the blocking put operation in UVM TLM, connecting a producer to a consumer via port and export, and implement a proper endpoint to avoid fatal connection errors.
Learn to add a blocking put implementation in the consumer, connect the export to the implementation, and establish the endpoint so producer data reaches the consumer without fatal errors.
Connect a producer and a consumer using a port to implementation approach in uvm, showing build and connect phases, a blocking put port, and data transfer without using an export.
Connect sub_producer data through a port to a consumer using a blocking put port and its implementation, illustrating port-to-port connections, build and connect phases, and hierarchy printing.
Demonstrate how a single producer communicates with multiple consumers through a port-export-implementation pattern in UVM, using a blocking put port, export, and implementation, connected in the environment and consumer phases.
Learn how the get port retrieves data from a consumer in UVM, contrasting it with the put port’s data flow. See a blocking get port example exchanging 12.
Implement two-way communication with a blocking transport port in uvm. Extend to non-blocking and mixed modes, using producer and consumer with port.transport for data exchange.
Explore the uvm analysis port for one-to-many data broadcast from a producer to multiple subscribers, using a write implementation and connect phase to link port to consumers.
Master the fundamentals of sequences in uvm, sending transactions to a driver via a sequencer, and executing multiple sequences in parallel using arbitration, lock/unlock, and grab/ungrab methods for timed access.
Explore fundamentals of sequence in UVM verification: from sequences and sequencers to drivers and interfaces, applying TLM put to DUT for write, read, and address-range test cases.
Design a transaction and sequence in uvm, connect sequencer, driver, and monitor inside an agent, and wire them into an environment with a scoreboard for dut verification.
Understand how a UVM environment coordinates transactions between driver, sequencer, and sequence objects, including grant, get next item, randomization, and non-blocking item done.
Generate random A and B in a UVM sequence, send them to a driver via a sequencer using the UVM do macro, and verify data printed by the driver.
Learn the intermediate UVM data-sending method: create a transaction, use start_item with embedded wait_for_grant, generate data after grant, and finish_item to send and wait_for_item_done.
Learn an alternate UVM sequence method to drive data: create a transaction, randomize A and B, and use start_item, finish_item, and automatic wait_for_item_done for five repeats.
Learn how to run multiple sequences in parallel with a UVM sequencer, implementing transaction items, start_item and finish_item signaling, and FIFO arbitration controlling parallel access.
Explore how to set and compare arbitration mechanisms in UVM, focusing on weighted arbitration: assign priorities, compute thresholds, and see higher-priority sequences gain more sequencer access.
Explore how arbitration mechanisms decide sequencer access in UVM, comparing random, strict FIFO, strict random, and weighted priority, and explain the effects of priority and equal-priority scenarios.
Learn how to hold sequencer access to complete multiple transactions in a single sequence using priority, lock, and grab methods, instead of alternating access.
Examine how a uvm verification environment uses a transaction class and three methods with sequences to send multiple transactions through a driver and sequencer, noting default behavior.
Override the default arbitration by setting the arbitration method to uvm_seq_arb_strict_fifo, demonstrate priority between sequences 1 and 2, and show how higher priority holds the sequencer until completion.
Commenting out priority switches to the default fifo, the lock method then lets a single sequence complete all three transactions before others gain sequencer access.
Apply fundamentals to real scenarios by verifying a combinational 4-bit adder and sequential synchronous 4-bit adders, and learn to connect fundamentals to build a verification environment.
Explore the verification environment for UVM essentials, detailing transaction, sequence, sequencer, driver, monitor, scoreboard, and agent components, plus environment and test class used to verify a DUT.
Learn how to verify a combinational adder (DUT) with a testbench, detailing the add module, 4-bit inputs A and B, a 5-bit sum Y, carry out, and an adder_if interface.
build the transaction class as a UVM sequence item, defining input ports a and b and output port y, using rand bit stimuli and field macros for core methods.
Extend a uvm_sequence to generate 10 random stimuli for the DUT. Create and randomize a transaction on grant, print a and b, and send to the driver.
Extend uvm_driver to create a driver that applies sequencer transactions to the dut via adder_if using tc. Use sequence_item_port.get_next_item and drive a and b non-blocking every 10 ns.
Extend the UVM monitor to capture DUT responses into a transaction and push it to the scoreboard via an analysis port, using A and A_if.
Extend uvm_scoreboard to receive monitor data, implement a comparison algorithm against the DUT response (no golden reference available), and report test pass or fail.
Register the agent class to the factory with uvm_component_utils, instantiate the monitor, driver, and sequencer in build, and connect the driver to the sequencer in connect.
Extend the environment class to build a UVM environment with a scoreboard and an agent, register to the factory, and connect the analysis port between the monitor and scoreboard.
Register the test class to the factory, add a sequence named gen and an environment in build, then raise and drop an objection to start gen via e.agent.sqr.
Add an interface in the testbench top, connect variables to DUT, set a virtual interface via UVM config DB, and run to view the ep waveform.
Compare combinational and sequential adders and implement a sequential adder in Verilog, using a 4-bit A and B input, a 5-bit Y output, and a clocked, synchronous reset.
Build a verification environment by adding a and y as bit data members with rand to the transaction class, and implement a generator extending UVM_sequence_item that drives driver via sequencer.
Register the driver class with the UVM factory, access the interface, and store sequencer data in a data container; reset the DUT and process items every two clock ticks.
Add an analysis port to the monitor to send DUT responses to scoreboard, implement the data transaction, and report test pass or fail by comparing data_y to data_a plus data_b.
Connect the driver and sequencer in the agent; connect the monitor and scoreboard port in the environment; start the sequence in the test class and delay last stimulus, then compare.
Generate a clock in the testbench with always #10, initialize signals, connect the interface to the DUT, and verify A+B=Y through monitor, driver, and scoreboard.
Writing Verilog test benches is always fun after completing RTL Design. You can assure clients that the design will be bug-free in tested scenarios. As System complexity is growing day by day, System Verilog becomes a choice for verification due to its powerful capabilities and reusability helping verification engineers quickly locate hidden bugs. The System Verilog lags structured approach whereas UVM works very hard on forming a general skeleton. The addition of the configuration database Shifts the way we used to work with the Verification Language in the past. Within a few years, verification engineers recognize the capabilities of UVM and adopted UVM as a defacto standard for the RTL Design verification. The UVM will have a long run in the Verification domain hence learning of UVM will help VLSI aspirants to pursue a career in this domain.
The course will discuss the fundamentals of the Universal Verification Methodology. This is a Lab-based course designed such that anyone without prior OOPS or system Verilog experience can immediately start writing UVM components such as Transaction, Generator, Sequencer, Driver, monitor, Scoreboard, Agent, Environment, Test. Numerous coding exercises, projects, and simple examples are used throughout the course to build strong foundations of the UVM.