Verification Academy

Search form

My Account Menu

  • Register
  • Log In
  • Topics
  • Courses
  • Forums
  • Patterns Library
  • Cookbooks
  • Events
  • More
  • All Topics
    The Verification Academy offers users multiple entry points to find the information they need. One of these entry points is through Topic collections. These topics are industry standards that all design and verification engineers should recognize. While we continue to add new topics, users are encourage to further refine collection information to meet their specific interests.
    • Languages & Standards

      • Portable Test and Stimulus
      • Functional Safety
      • Design & Verification Languages
    • Methodologies

      • UVM - Universal Verification Methodology
      • UVM Framework
      • UVM Connect
      • FPGA Verification
      • Coverage
    • Techniques & Tools

      • Verification IP
      • Simulation-Based Techniques
      • Planning, Measurement, and Analysis
      • Formal-Based Techniques
      • Debug
      • Clock-Domain Crossing
      • Acceleration
  • All Courses
    The Verification Academy is organized into a collection of free online courses, focusing on various key aspects of advanced functional verification. Each course consists of multiple sessions—allowing the participant to pick and choose specific topics of interest, as well as revisit any specific topics for future reference. After completing a specific course, the participant should be armed with enough knowledge to then understand the necessary steps required for maturing their own organization’s skills and infrastructure on the specific topic of interest. The Verification Academy will provide you with a unique opportunity to develop an understanding of how to mature your organization’s processes so that you can then reap the benefits that advanced functional verification offers.
    • Universal Verification Methodology (UVM)

      • UVMF - One Bite at a Time
      • Introduction to UVM
      • Basic UVM
      • UVM Debug
      • Advanced UVM
      • UVM Connect
    • Featured Courses

      • Portable Stimulus Basics
      • Introduction to DO-254
      • SystemVerilog OOP for UVM Verification
      • Power Aware Verification
      • Power Aware CDC Verification
      • Assertion-Based Verification
      • Metrics in SoC Verification
    • Additional Courses

      • Clock-Domain Crossing Verification
      • An Introduction to Unit Testing with SVUnit
      • Evolving FPGA Verification Capabilities
      • SystemVerilog Testbench Acceleration
      • Testbench Co-Emulation: SystemC & TLM-2.0
      • Verification Planning and Management
      • VHDL-2008 Why It Matters
    • Formal-Based Techniques

      • Formal Assertion-Based Verification
      • Formal Coverage
      • Formal-Based Technology: Automatic Formal Solutions
      • Getting Started with Formal-Based Technology
      • Handling Inconclusive Assertions in Formal Verification
      • Sequential Logic Equivalence Checking
    • Analog/Mixed Signal

      • AMS Design Configuration Schemes
      • Improve AMS Verification Performance
      • Improve AMS Verification Quality
  • All Forum Topics
    The Verification Community is eager to answer your UVM, SystemVerilog and Coverage related questions. We encourage you to take an active role in the Forums by answering and commenting to any questions that you are able to.
    • UVM Forum

      • Active Questions
      • Solutions
      • Replies
      • No Replies
      • Search
      • UVM Forum
    • SystemVerilog Forum

      • Active Questions
      • Solutions
      • Replies
      • No Replies
      • Search
      • SystemVerilog Forum
    • Coverage Forum

      • Active Questions
      • Solutions
      • Replies
      • No Replies
      • Search
      • Coverage Forum
    • Additional Forums

      • Announcements
      • Downloads
      • OVM Forum
  • Patterns Library
    The Verification Academy Patterns Library contains a collection of solutions to many of today's verification problems. The patterns contained in the library span across the entire domain of verification (i.e., from specification to methodology to implementation—and across multiple verification engines such as formal, simulation, and emulation).
    • Implementation Patterns

      • Environment Patterns
      • Stimulus Patterns
      • Analysis Patterns
      • All Implementation Patterns
    • Specification Patterns

      • Occurrence Property Patterns
      • Order Property Patterns
      • All Specification Patterns
    • Pattern Resources

      • Start Here - Patterns Library Overview
      • Whitepaper - Taking Reuse to the Next Level
      • Verification Horizon - The Verification Academy Patterns Library
      • Contribute a Pattern to the Library
  • All Cookbooks
    Find all the methodology you need in this comprehensive and vast collection. The UVM and Coverage Cookbooks contain dozens of informative, executable articles covering all aspects of UVM and Coverage.
    • UVM Cookbook

      • UVM Basics
      • Testbench Architecture
      • DUT-Testbench Connections
      • Configuring a Test Environment
      • Analysis Components & Techniques
      • End Of Test Mechanisms
      • Sequences
      • The UVM Messaging System
      • Other Stimulus Techniques
      • Register Abstraction Layer
      • Testbench Acceleration through Co-Emulation
      • Debug of SV and UVM
      • UVM Connect - SV-SystemC interoperability
      • UVM Versions and Compatibility
      • UVM Cookbook
    • Coding Guidelines & Deployment

      • Code Examples
      • UVM Verification Component
      • Package/Organization
      • Questa/Compiling UVM
      • SystemVerilog Guidelines
      • SystemVerilog Performance Guidelines
      • UVM Guidelines
      • UVM Performance Guidelines
    • Coverage Cookbook

      • Introduction
      • What is Coverage?
      • Kinds of Coverage
      • Specification to Testplan
      • Testplan to Functional Coverage
      • Bus Protocol Coverage
      • Block Level Coverage
      • Datapath Coverage
      • SoC Coverage Example
      • Requirements Writing Guidelines
      • Coverage Cookbook
  • All Events
    No one argues that the challenges of verification are growing exponentially. What is needed to meet these challenges are tools, methodologies and processes that can help you transform your verification environment. These recorded seminars from Verification Academy trainers and users provide examples for adoption of new technologies and how to evolve your verification process.
    • Upcoming & Featured Events

      • DVClub- Austin, TX | 12/11
      • Events Calendar
    • On Demand Seminars

      • UVM 1800.2 & Updated UVM Cookbook
      • Debug
      • FPGA Verification
      • All On-Demand Seminars
    • Recording Archive

      • DAC 2019 Session Recordings
      • User2User Silicon Valley 2019
      • Portable Stimulus from IP to SoC
      • Wilson Research Group - 2018 Results
      • All Recordings
    • Mentor Training Center

      • SystemVerilog for Verification
      • SystemVerilog UVM
      • SystemVerilog UVM Advanced
      • Instructor-led Training
    • Mentor Learning Center

      • SystemVerilog Advanced OOP
      • UVM Transactions and Sequences
      • UVM Monitors and Agents
      • Functional Verification Library
  • About Verification Academy
    The Verification Academy will provide you with a unique opportunity to develop an understanding of how to mature your organization's processes so that you can then reap the benefits that advanced functional verification offers.
    • Blog & News

      • Verification Horizons Blog
      • Academy News
      • Technical Resources
    • Verification Horizons Publication

      • Verification Horizons - December 2019
      • Verification Horizons - June 2019
      • Verification Horizons - February 2019
      • Issue Archive
    • About Us

      • Verification Academy Overview
      • Subject Matter Experts
      • Contact Us
    • Training

      • Questa® & ModelSim®
      • SystemVerilog
      • Functional Verification Library
  • Home /
  • Verification Horizons /
  • June 2017 /
  • Smoothing the Path to Software-Driven Verification with Portable Stimulus

Smoothing the Path to Software-Driven Verification with Portable Stimulus

Verification Horizons - Tom Fitzpatrick, Editor

Smoothing the Path to Software-Driven Verification with Portable Stimulus by Matthew Ballance - Mentor, A Siemens Business

Designs are becoming more complex, and increasingly include a processor – and often multiple processors. Because the processor is an integral part of the design, it's important to verify the interactions between software running on the processor and the rest of the design. Verification and validation of the hardware/software boundary cannot reasonably be deferred until prototype bring-up in the lab, because software is so critical to the operation of today's systems. Or, at least, verification teams do so at their own peril. I'm sure we've all heard the nightmare scenarios where, for example, a team discovered in the lab that the processor's bus was connected to the design in reverse order, or the processor was unable to power up again from low-power mode.

HW/SW STEPWISE REFINEMENT

An obvious solution, of course, is to do more verification around the hardware/software boundary during the traditional verification process. However, we can't just jump from hardware-centric verification to attempting to run a full application stack. With the complexity and voluminous debug logs that result from attempting to execute a large amount of software, tracking down simple bugs gets really complicated.

A productive approach is to verify everything we can in the simplest verification environment that reasonably allows us to exercise the target functionality, has the greatest visibility, and has the least activity that is extraneous to the test intent.
In this article we'll look at a simple example involving register-access verification. Verifying that registers of an IP can be correctly written and read by the processor is a key integration-verification task. Even simple SoCs contain hundreds of registers, and creating the tests to verify that the processor can read and write each of them can be time consuming.

Figure 1 shows a simple SoC with flash and DDR memory, a tightly-coupled memory, and a UART and DMA engine whose registers are accessed via a low-speed peripheral bus.

Figure 1. Simple SoC


While we will eventually need to verify that code running on the processor can access IP registers, we can focus the verification task just a bit more by starting with UVM-based verification. Verifying the memory subsystem in UVM first will give us more confidence when bringing up software on the embedded processor. Using Mentor's Questa® inFact portable stimulus tool will allow us to retarget the same test intent to a UVM and embedded soft-ware environment, saving test-development time.

USING GRAPHS TO DESCRIBE REGISTERS

Questa® inFact uses a declarative graph-based input description, which provides the power of constraint programming and adds the ability to specify decisions in an iterative fashion. This ability to make decisions iteratively is very helpful when it comes to specifying the constraints for accessing registers.

We start by capturing the core attributes of a memory-test operation: address, access size, write data, and a write mask. The write mask specifies which bits are read/write, and which must be ignored for the purposes of checking.

Figure 2. Core Register Access Struct

struct regacc {
	meta_action  addr[unsigned 31:0];
	meta_action  size[unsigned 7:0];
	meta_action  wr_data[unsigned 31:0];
	meta_action  wr_mask[unsigned 31:0];
 
	constraint size_c  {
		size  > 0;
		size inside [1,2]  | |  (( size %4)  = = 0);
	}
	action  body;
}

An action is a unit of behavior to be carried out in the target verification environment. Later on we'll see how changing the implementation of the body action allows us to easily retarget the register-access test intent to UVM and embedded-software environments.

The register access descriptor shown in Figure 2 doesn't include any details of the IPs in our system. We next need to add these restrictions in. Our DMA engine (the Wishbone DMA Core from opencores.org) has a set of core registers, and then an array of channel-descriptor registers. Using a graph-based description allows us to describe the register address iteratively.

The graphical description in Figure 3 shows the process for selecting a DMA-register address:

  • Select a core register or the array of channel-control registers (dma_reg)
  • If the channel-control registers are selected
    • Select which channel (dma_ch)
    • Select which channel register is being targeted (dma_ch_reg)

Figure 3. DMA Register Address Selection


Figure 4. DMA Register Address Selection Rules

symbol dma_regacc  =
	dma_regs_c 
	dma_reg 
	if  {dma_reg  = =  IP_DMA_CH} 
 		(dma_ch  dma_ch_reg) 
	else eta
;

Figure 4 shows the textual description of this process.

There are, of course, more detailed constraints for specifying the register address and write-mask which are coded in the constraints shown in Figure 5. Note that this constraint is marked as 'dynamic', which means that it only applies once activated within the graph – in this case, once we've decided to access a DMA register. While these constraints were created by hand, they could also be generated from a machine-readable register description, such as IP-XACT, SystemRDL, etc.

Figure 5. DMA Register Address Selection Constraints

constraint  dma_regs_c dynamic {
		size  = = 4;
		if  (dma_reg  = = IP_DMA_CSR)  {
			addr  = = (IP_DMA_BASE  +  0x00000000) ;
			wr_mask  = = 0x00000001 ;
		}
		if   (dma_reg  = =  IP_DMA_INT_MSK_A)  {
			addr  = = (IP_DMA_BASE  +  0x00000004) ;
			wr_mask  = = 0x7FFFFFFF ;
		}
		if   (dma_reg  = =  IP_DMA_INT_MSK_B)  {
			addr  = = (IP_DMA_BASE  +  0x00000008) ;
			wr_mask  = = 0x7FFFFFFF ;
		}
		if   (dma_reg  = =  IP_DMA_INT_SRC_A)  {
			addr  = = (IP_DMA_BASE  +  0x0000000C) ;
			wr_mask  = = 0x7FFFFFFF ;
		}
		if   (dma_reg  = =  IP_DMA_INT_SRC_B)  {
			addr  = = (IP_DMA_BASE  +  0x00000010) ;
			wr_mask  = = 0x7FFFFFFF ;
 
		}
		if   (dma_reg  = =  IP_DMA_CH)  {
			addr  = = IP_DMA_BASE  +  (dma_ch_reg * 4) + (0x20  *  ( dma_ch +1) ) ) ;
 
		if   (dma_ch_reg  = =  IP_DMA_CH_CSR)  { 
			wr_mask  = = 'b0000_0000_1111_1110_0001_1111_1111 ;
		}
		if   (dma_ch_reg  = =  IP_DMA_CH_SZ)  { 
			wr_mask  = = 0xFF0FFF ;
		}
		if   (dma_ch_reg  = =  IP_DMA_CH_A0  | |  
			dma_ch_reg = = IP_DMA_CH_A1)  { 
			wr_mask  = = 0xFFFFFFFC ;
		}
		if   (dma_ch_reg  inside  = =  [IP_DMA_CH_AM0, IP_DMA_CH_AM1])  { 
			wr_mask  = = 0xFFFFFFF0 ;
		}
		if   (dma_ch_reg  inside  = =  [IP_DMA_CH_DESC, IP_DMA_CH_SWPTR])  { 
			wr_mask  = = 0xFFFFFFFC ;
		}
	}
}

Once we integrate the DMA, UART, and TCM portions of our register-access graph, we arrive at the graph shown in Figure 6. We can view this as a flow chart: first, we decide which IP to access, then the graph branches based on the selected IP and specific choices are made. For example, the left-most graph branch contains DMA-specific decisions.

Figure 6. Simple SoC Register Access Graph


TARGETING TESTS

Even our small SoC has over 250 registers, and a real SoC would have many times more. We need to ensure that we access all of these registers, and that we access them in some random order. We might also want to focus our testing a bit – for example, just test the UART registers.

Questa® inFact allows a combination of constraints and graph-coverage goals to be used to focus testing on the goals to be achieved. Constraints specify which tests are allowed to be generated, while coverage goals prioritize systematic generation of some tests. For example, a constraint could be used to specify that the UART isn't currently ready to be tested. A coverage goal is used to specify that the focus of a given test is the DMA engine, but other available IPs can be targeted once that goal is achieved.

The coverage goal (the blue-shaded region) shown in Figure 7, on the following page, focuses test activity on the DMA registers for the current test. Questa® inFact will generate tests that systematically access the DMA registers in a pseudo-random order, then generate a mix of accesses to DMA, UART, and TCM.

Figure 7. Coverage Goal Focused on DMA


MAPPING TO A UVM ENVIRONMENT

Thus far, the description of register-access testing that we've created is independent of any verification environment. We now need to provide a little glue logic to connect our test graph into a subsystem-level verification environment.

In our UVM subsystem-level environment, we've replaced the RTL model of the processor with a bus functional model (BFM) to access registers across the interconnect. Our register-test graph is encapsulated in a UVM virtual sequence that will access registers via the BFM.

Figure 8. Subsystem-level Verification Environment


Our base 'CPU' virtual sequence provides access to the BFM via a class API that supports reads and writes of various sizes. We've added a specific 'memcheck' sequence that carries out write, read-back, and check inside a 'do_memcheck' task, which is shown in Figure 9.

Figure 9. UVM do_memcheck task

class  or1k_memcheck_vseq  extends  or1k_cpu_vseq ;
	`uvm_object_utils (or1k_memcheck_vseq)
 
	task do_memcheck (or1k_memcheck_c c) ;
		bit [31:0] read_data = 0 ;
 
		case (c.size)
			1: begin
				m_bfm.write8 (c.addr, c.wr_data) ;
				m_bfm.read8 (c.addr, read_data) ;
			end
			2: begin
				m_bfm.write16 (c.addr, c.wr_data) ;
				m_bfm.read16 (c.addr, read_data) ;
			end
			4: begin
				m_bfm.write32 (c.addr, c.wr_data) ;
				m_bfm.read32 (c.addr, read_data) ;
			end
		endcase
 
		if  (read_data != (c.wr_data & c.wr_mask))  begin 
			`uvm_error  (get_name () , $psprintf (
					"Access to 'h%08h failed: Expect  'h%08h ; Receive  'h%08h" , 
					c.addr, (c.wr_data & c.wr_mask), 
					read_data));
		end
	endtask

The mapping information needed to connect our register-test graph to the do_memcheck task in the virtual sequence is collected in a file – target.rseg in this case. The mapping information is shown in Figure 10.

The mapping information specifies:

  • That our graph should be encapsulated in a class that extends from or1k_memcheck_vseq
  • That we should use the or1k_memcheck_c class to represent the or1k_soc_regacc struct in the UVM environment
  • That the do_memcheck task should be called when the 'body' action within or1k_soc_regacc executes

Figure 10. UVM Sequence Target Mapping

attributes rule_graph  {
	base_class = "or1k_memcheck_vseq";
}
 
attributes or1k_soc_regacc  {
	type = "or1k_memcheck_c";
}
 
attributes or1k_soc_regacc.body {
	action_stmt = "do_memcheck (${item});";
}

With just these few lines of code, we can now run our register-test graph in our UVM environment. This allows us to verify the basics of register connectivity, and debug any issues using our standard UVM and SystemVerilog debug tools.

MAPPING TO EMBEDDED SW

But, of course, verifying that our BFM can access register memories doesn't definitively ensure that our processor will be able to. Consequently, it's still important to run register-access tests as embedded software on the processor. In its simplest form, this full SoC verification environment might look like what is shown in Figure 11.

Figure 11. Software-Driven Verification Environment


In this case, we will create a series of tests written in 'C' that write and read-back registers using the processor. Our tests will use a do_memcheck function to perform the actual write, read-back, and check. This function is shown in Figure 12.

Figure 12. Embedded software do_memcheck function

void  do_memcheck (
		uint32_t		addr,
		uint32_t		size,
		uint32_t		wr_data,
		uint32_t		wr_mask
		)  {
	uint32_t  rd_data;
 
		switch (size)  {  
		case 1:  {
			write8(addr, wr_data);
			rd_data  =  read8(addr);
		}  break;
		case 2:  {
			write16(addr, wr_data);
			rd_data  =  read16(addr);
		}  break;
		case 4:  {
			write32(addr, wr_data);
			rd_data  =  read32(addr);
		}  break;
		}
 
		if (rd_data != (wr_data & wr_mask))  {
			error(addr, rd_data, (wr_data & wr_mask));
		}
}

Just as with the UVM environment, we need to specify how the graph maps to the embedded software environment. The mapping information is shown in Figure 13.

Figure 13. Embedded software mapping

attributes rule_graph  {
	include +="
		#include \ "or1k_memcheck.h\"
	" ;
 }
 
attributes or1k_soc_regacc.body  {
	action_stmt = "
		do_memcheck(${addr}, ${size}, ${wr_data}, ${wr_mask});
	" ;
 }

The mapping information specifies the following:

  • That the header file or1k_memcheck.h must be included. This file declares the do_memcheck function
  • That the function do_memcheck must be called each time the body action executes, passing the values of the addr, size, wr_data, and wr_mask fields

GENERATING C-TESTS

Because we've described a graph-based model of the register tests to perform, we now have a lot of flexibility in how we generate specific sets of tests. Figure 14 shows one example of a generated test. In this case, we've allowed inFact to target all three IPs, but restricted the test to just five iterations through the graph.

Figure 14. Example Register Test

void or1k_subsys_regtest_seq_test(void) {
	do_memcheck(0x80000074,   4,  0xcc831f7d,  0xfffffff0) ;
	do_memcheck(0x80000004,   4,  0xe8f9dd44,  0x7fffffff) ;
	do_memcheck(0x90000528,   16, 0xd51f56e2,  0x3651b705) ;
	do_memcheck(0x9000005f,   1,  165,  0xfffffff0) ;
	do_memcheck(0x8000000c,   4,  0x763b2c6,  0x7fffffff0) ;
 }

As you can see, the generated test is a directed test with randomized values filled in by inFact during the generation process. While this specific test will always do the same thing every time it is run, we can achieve more randomness across regression runs by re-generating the test with a different seed each time the regression runs.

In order to achieve coverage of the register-access goals that we described earlier, we will need to generate more specific tests. Because all of these tests are generated from a single declarative model, it's easy to simply change the options to the test-generation program in order to move between running many tests that each make a few calls to do_memcheck per test to running a few tests that each make many calls to do_memcheck per test. It's also easy to adjust targeted coverage goals to, for example, generate a series of tests that only focus on DMA register tests.

SUMMARY

Taking a step-wise approach to verifying interactions between embedded processors and the IPs in the rest of the design saves time by finding bugs earlier in the verification process when they're easiest to debug and correct. Portable stimulus allows high-quality tests to be generated from test intent that is described once, and retargeted to multiple environments. This addresses the major challenges of taking stepwise approach, which are the amount of duplicated effort to execute test intent in multiple places, as well as the need to create embedded software tests using low-productivity directed tests. In this article we've seen how a single description of test intent for testing access to SoC registers, as a part of SoC integration testing, can be easily targeted to both UVM and embedded-software environments. We've seen how this test intent is described and targeted to specific environments with Mentor's Questa® inFact portable stimulus tool.

Next time you start planning for SoC integration testing, consider how portable stimulus and a step-wise testing approach can benefit your verification process!

Back to Top

Table of Contents

Verification Horizons Articles:

  • What Does Improving Your Golf Swing Have in Common with Verification?

  • Parallel Debug: A Path to a Better Big Data Diaspora

  • Portable Stimulus Modeling in a High-Level Synthesis User's Verification Flow

  • Smoothing the Path to Software-Driven Verification with Portable Stimulus

  • Verification Planning with Questa® Verification Management

  • MIPI® CSI2 TX IP Verification Using Questa® VIPs

  • Converting Legacy USB IP to a Low Power USB IP

  • Understanding the UPF Power Domain and Domain Boundary

  • Automation and Reuse in RISC-V Verification Flow

  • Emulation – A Job Management Strategy to Maximize Use

  • RTL CDC Is No Longer Enough — How Gate-Level CDC Is Now Essential to First Pass Success

  • Formal Verification: Not Just for Control Paths

© Mentor, a Siemens Business, All rights reserved www.mentor.com

Footer Menu

  • Sitemap
  • Terms & Conditions
  • Verification Horizons Blog
  • LinkedIn Group
SiteLock