Advancing HW/SW Co-Verification Methodology

Table of Contents


Overview

The term hardware/software (HW/SW) co-verification was coined in the mid 1990s to describe a process that allows embedded system software to be executed on a simulated representation of the hardware design. The simulated representation of the hardware has usually meant a Verilog or VHDL description running in a logic simulator. The concept of logic simulation has since been extended to allow for other representations of the hardware that are not the final implementation, including logic emulation systems and other prototyping methods.

As designs become more complex, initial co-verification solutions are running out of stream. At the same time, many complex SoC designs are still using nothing more than a full-functional simulation model of a microprocessor and waveforms to debug complex hardware and software. A full-functional model of a microprocessor fetching and executing code in a logic simulator is not co-verification if the only means of debugging software are waveforms and assembly language traces.

The difficulty of the problem can be seen by looking at the vast array of alternatives available to verify both hardware and software before first silicon is available. This paper will help engineers break down the SoC verification problem into digestible portions and help explain the best methods needed to successfully bring an SoC design to market. The outline is derived from the logical steps of the SoC software development process. It maps the software development process onto the necessary hardware execution and debugging technologies required for success. Once the software development process is understood, a solution is proposed that can be used as an outline for creation of an SoC verification plan.


Benefits of Performing Hardware/Software Co-Verification

The ultimate goal of co-verification is to get the entire system -- hardware and software -- working prior to prototype by providing better visibility into the behavior of both hardware and software. Co-verification achieves this by providing two primary benefits:

  1. Software engineers have much earlier access to the hardware design. This allows software designers to develop code and test it concurrently with hardware design and verification. Performing these activities in parallel shaves time from the project schedule compared to the serial method of waiting for the prototype to begin software testing. Moreover, the early involvement of the software team results in a much better understanding of the underlying hardware operation.
  2. Co-verification provides additional stimulus for the hardware design. In fact, it can provide the true stimulus that will occur in the embedded system. This improves hardware verification when compared to using a contrived testbench that may or may not represent real system conditions. Increased confidence in the hardware design is invaluable.

By running hardware/software co-verification, a wide range of problems can be found and fixed prior to silicon, such as register map discrepancies, problems in the boot code, errors in DMA controller programming, RTOS boot and configuration errors, bus pipelining problems, and cache coherency mishaps. Some of the errors will be software problems and some hardware related. Attacking this laundry list of example problems must be done using a logical and well-defined verification strategy. The key to a successful project is to apply the correct tools to the problem and always to understand what types of problems you are looking for and what parts of the system are assumed to be working at each stage of the project.


Overview of SoC Development

The SoC development process involves many facets. The traditional notion of the hardware design being the device under test (DUT) and the testbench being used to stimulate the DUT is outdated. The DUT now includes software, and the testbench must verify how hardware and software operate together. This paper is built around a common approach used for SoC software development and maps the proper hardware design technologies onto this five-step software process.

Five distinct types of embedded system software have been identified, with software design proceeding in this order. The software content (i.e., lines of code) increases with each step: 

  • System initialization software and hardware abstraction layer (HAL)
  • Hardware diagnostic test suite
  • Real-time operating system (RTOS)
  • RTOS device drivers
  • Application software

The abstraction of the hardware and the assumptions made about the stability and functionality also increases with each stage of software development.

Four distinct methods used for the execution of the hardware design description have been identified and are commonly used in SoC design:

  • Logic Simulation
  • Simulation Acceleration
  • Hardware Emulation
  • Hardware Prototyping

Each hardware execution method has specific debugging techniques for both hardware and software associated with it, each with its own set of benefits and limitations. These range from the slowest execution method, with the most thorough debugging, to the fastest, with less debugging. As an example, a common SoC built around the popular ARM family of microprocessors will be described. The Axis ReConfigurable Computing (RCC) platform used in the Xcite® and Xtreme® products will be used to illustrate how to apply the concepts discussed. This single platform is used for logic simulation, simulation acceleration, hardware emulation, and co-verification. The Axis XpertT HW/SW Co-Verification product will be used to demonstrate software-debugging concepts.


The Debugging Loop

Beyond just tools and debugging methods there is one more crucial area to cover, the human interaction between hardware and software engineers. The optimization of this interaction is equally as important as the optimization of the hardware and software itself. This is best illustrated by describing a common interaction model used in the early stages of many projects today.

A typical project will first partition the system into hardware and software and follow with a register map specification, usually written with a word processor, that describes the software interface to the custom hardware. As time passes, these registers are changed, but the specs are not updated. The written descriptions are either incorrect or not clearly understood by the software engineers. Hardware and software engineers have different concepts and methods for describing the system functionality. For example, software engineers don't usually have a concept of logic signals being "active low."

To debug these systems, the process starts when software engineers compile code and prepare memory image files for execution. Because they are unfamiliar with logic simulation and emulation tools, they pass the image file over to the hardware or verification engineers who run the test.

When the test fails, the verification engineer tries to isolate the problems, and presents the result to a design engineer who is familiar with the specific part of the design that may have a problem. The design engineer analyzes and fixes the problem and runs the test again.

If the problem is in the software, then the software engineer must be called in to inspect the problem. For the software engineer to debug the problem, he needs the help of the verification engineer who understands waveforms from the simulation and can correlate it to the software.

Finally, the software engineer generates a fix, and the process starts all over. This iterative cycle of throwing results over the wall among three groups struggling to work together slows down the progress of the project.


Figure 1: Typical Debugging Cycle

Co-verification aims to tighten this debugging loop by allowing all groups to work independently and concurrently as much as possible. Any tools or methods that empower software engineers to find and fix problems with less intervention by verification and hardware design engineers are of great benefit to the entire project.

Given this background, the next section will move into the embedded software phases of SoC design and outline best practices for co-verification success.


System initialization and HAL

The first coding task is to write and test the processor initialization software. This code includes configuring the operating modes and peripherals (things like cache configuration, memory protection unit or MMU programming, interrupt controller configuration, timer setup, and DRAM initialization). This is a tedious coding task using assembly and C languages, but important since all other software relies on it, including the final product.

The hardware abstraction layer is the next layer of software that works with the initialization code to provide a common interface for higher-level software to use for hardware-specific functionality after the system is initialized. The HAL abstracts the underlying hardware of a processor architecture and the platform to a level sufficient for the RTOS kernel to be ported onto the platform. For example, consider a system that has an interrupt controller with a prioritized interrupt scheme. The RTOS porting engineer would like to change the priority using a simple C function and a priority level, like ipl(5), to set the priority level to 5. The detail of disabling interrupts and using an atomic read-modify-write sequence to change the interrupt controller registers and then enabling interrupts again are not interesting or necessary.

Many complex system-on-a-chip (SoC) projects use nothing more than a full-functional model of the microprocessor core in a logic simulator to write and debug this code. Software debugging with waveforms requires a true guru who understands hardware and software and can disassemble instructions in his head using instruction fetches on the data bus.

For the ARM SoC example, the ideal debugging solution for early development of system initialization and HAL code is one based on a cycle-accurate instruction set simulation model tightly coupled to a logic simulator containing the SoC hardware design. This provides interactive, graphical software debugging for the software engineer to single step through the code and verify register and memory contents with excellent control. Simulation performance is less important because the code must be verified line-by-line and the number of lines of code is relatively small. A standard Verilog simulator such as Xsim® is more than adequate to execute the hardware design and provides good visibility into the hardware. Interactive software debugging provided by Xpert's graphical debugger interface is the ideal way to control software execution and very software operation.

It is common for many hardware bugs to be encountered during this phase since it generally occurs soon after the blocks of the SoC have been integrated into a full-chip simulation and is the first time all of the subsystems are working together using the defined hierarchy of shared busses.


Diagnostic Suite

Once the initialization software and HAL are stable, the next phase of software development consists of developing a detailed test suite for the hardware design. In the past this usually took the form of a hardware testbench. While testbenches are still necessary to provide stimulus for external interfaces such as networking protocols, the software now serves as the testbench for the CPU core bus. A comprehensive set of diagnostic tests should be developed to verify each subsystem and peripheral. This starts with the memory subsystem, progresses to interrupt testing, and then moves to other IP blocks like timers, DMA controllers, video controllers, MPEG decoder, and other specialty hardware. Most of these tests do not see their way into the final product but they are very important because they build the case for a solid hardware design. Creating the programs gives the software engineers a very good understanding of the hardware and serves as a chance to learn about the hardware specifics in a more secluded environment.

It is during this development of diagnostic tests that the logic simulator begins to become the bottleneck of the verification environment. As tests run longer and longer and the number of tests increases, it becomes increasingly difficult to both verify the entire hardware design and to continue to run the old tests as hardware and software errors are fixed. This phase is also the most crucial since it is where most of the hardware bugs are found. Debugging tools for both software and hardware at this stage are very important.

The ideal solution uses simulation acceleration to increase the performance of logic simulation over what is a possible using an ordinary software simulator. A simulation environment running at 10 to 100 Hz is not fast enough for software engineers to run and tests anymore. Moreover, the memory optimization techniques commonly used for co-verification are not useful because the main purpose of the diagnostics is hardware verification. To abstract the hardware using time domain techniques and stray from a cycle-accurate simulation goes against the purpose of the tests. A simulation acceleration system that runs at speeds of 1 to 10 kHz is the ideal platform for simulation performance and debugging.

During this phase of the project, debugging is equally as important as speed. Traditional hardware debugging techniques such as waveform dumping are far too inefficient. The VCD-on-Demand feature of RCC allows engineers to extract all node history values from any point in simulation without re-simulating from time zero. This is another reason to deploy simulation acceleration during this phase. The combination of Xcite for simulation acceleration and Xpert for software debugging is the best way to create and verify the hardware diagnostic suite.

As the test suite grows many tests are run in parallel, probably overnight in a batch environment. If specific tests fail, engineers must analyze the results. While hardware engineers are familiar with post-processing debugging methods, software engineers are not. A debugging method that allows software engineers to inspect the test results without re-running the test is ideal. For the ARM example a technique called Instant ReplayT is provided by Xpert for ARM processors.


Instant Replay Software Execution using Instruction Set Simulators

During batch simulation, a compressed file is created containing bus transactions at the processor interface. The memory transactions, including address, data, and simulation timestamp along with interrupt information, are "recorded" into this file. After the simulation is complete, software engineers can start the instruction set simulator and software debugger and "re-run" the software execution sequence. However, this time instead of interacting with hardware simulation, the results are read from the recorded file. This "playback" of the bus interface replicates the exact sequence of software execution.

 

Figure 2: Using Instant Replay

Because the simulation now runs at MHz speeds, software engineers can re-run the software as many times as needed to find the problem -- without looking at any simulation waveforms. The simulation timestamp is also provided at any time to help correlate the software and hardware execution. This record and playback methodology makes Xpert the ideal way to debug long simulation tests that make interactive debugging unproductive.


Real-time operating system (RTOS)

One of the great benefits of this methodology and the diagnostic test suite is that the hardware, initialization sequence, and HAL are assumed good (pretty close, anyway) when the real time operation system work begins. The first assumption of the RTOS engineer is that the hardware is stable.

The initial RTOS work consists of just getting it to boot on the platform. How big a task the RTOS is depends on how standard the platform is and how well the HAL was designed. During the initial porting phase, device drivers for application specific hardware may be missing, but the RTOS can still boot.

The RTOS port is an ideal place to take advantage of memory optimizations commonly used in co-verification such as software memory models. Software memory models use a memory that is tightly coupled to the instruction set simulator to retrieve instructions at a much faster rate than using logic simulation. The result is less simulation detail on how the ARM SoC would work but increased performance. Since the instruction fetch path is well verified, this is where using the memory optimizations make sense, not back in the diagnostic test suite as a workaround for a low logic simulator. Xpert includes important memory optimizations for software memory models tightly coupled to the instruction set simulator to increase software execution performance.


Device Drivers

The final stage of verifying the hardware design and system software is to develop and test the remainder of the device drivers for the RTOS. For the RTOS porting work and the device drivers, the first attempt should be done using simulation acceleration mode. Once the drivers are verified a faster hardware execution method can be used.

Once the RTOS is booted and stable, future work can be done using a faster execution method such as an emulation system or a prototype. Here debugging is a bit more difficult, but the number of hardware bugs is very small. The choice of emulation versus prototyping is a complex one. Several factors are involved but the primary factors revolve around the number and type of required interfaces to exercise the SoC and the benefits gained by running at prototyping speeds. A tradeoff decision is required to assess the benefits of prototyping speed such as 20 MHz versus emulation speeds of less than 1 MHz in exchange for the debugging difficulty. The decision also depends on the design confidence in the testbenches used to verify interfaces in simulation acceleration mode. The Xtreme product from Axis provides interfaces to target systems used to verify real-world interfaces and increase design confidence. Xtreme provides the necessary performance to execute the RTOS and device drivers. The combination of Xtreme with a target board containing the ARM silicon is the ideal solution to obtain the next level of performance, 1-2 orders of magnitude over that of acceleration mode.


Application Software

Once the platform is complete, it is time to test application software. At the application level the hardware is assumed correct and becomes more like workstation programming. If the application crashes it can be safely assumed it is a software problem, not something wrong with the hardware. Projects that are too large for software-based logic simulation have long turned to logic emulation systems such as Xtreme to gain speeds of up to 1 MHz and access to hardware interfaces to real world stimuli. More recently, a need has developed to run at speeds of 20 MHz or more. This has fueled the use of prototyping for higher speeds at the expense of visibility. These platforms are best for application development. Sometimes even waiting for silicon is best for applications: this depends on confidence in the hardware design and whether everything was verified.

Applications usually want to interface to real network traffic, see things on the screen, and use the pointer or mouse. During application development, hardware and lower-level software bugs are few and far between and the software engineer is focused on providing robust applications with differentiating features for end users.


Summary of Verification Flow

Below is a summary of the ARM SoC verification flow described using Axis products.

  1. Assemble full chip RTL netlist and testbench for Xsim simulation. ARM SoC simulation should be constructed to allow both the Xpert ARM model and the ARM design signoff model (DSM) to be used.
  2. Run Xsim to verify operation of device sub-systems including memories and peripherals using the software debugger. Without writing or loading any software targeted reads and writes can be generated from the debugger to make sure all memories and registers are working without any bus conflicts.
  3. Test and debug ARM initialization software and HAL using Xpert and Xsim. Performance in software simulation is typically less than 200 cycles/sec, but code is small and graphical debugging provides control and visibility of the design.
  4. Develop and test a complete suite of diagnostic tests to obtain maximum hardware design coverage. This is where most of the hardware design is verified and debugged. As test suite grows, transition the design to RCC for simulation acceleration. Now performance is improved to 1,000 - 5,000 cyles/sec with full cycle accuracy. Utilize Instant Replay to help debug test failures. When all test pass, the hardware design should have very few bugs remaining and can be assumed "known good".
  5. Port real-time operating system (RTOS) and associated device drivers. This work begins in acceleration mode with Xpert. Using Xpert's memory optimizations performance is approximately 20,000 - 50,000 cycles/sec. Once the RTOS is booted, transition to emulation with Xtreme and an ARM target board for higher performance and testing of other interfaces such as video display or communication protocols. Now performance is approximately 200,000 cycles/sec.
  6. Develop application software using Xtreme or move to prototype depending on performance requirement and number of application developers requiring access to hardware.

The key to this verification flow is the smooth transition from simulation to acceleration to emulation. Axis is in a unique position to provide this complete flow for SoC verification using RCC technology as the hardware execution platform, VCD-on-demand for hardware debugging, and Xpert for software execution and debugging. This allows the verification tasks to be done using logical transitions between project phases. One example of a common mistake is to attempt to eliminate the simulation acceleration mode of execution by using an emulation system that is disjoint from software simulation. When this occurs software simulation runs out of steam during the diagnostic test suite phase and the design is forced to move to emulation too early. Now time is wasted trying to debug many hardware problems as well as software bugs in a difficult emulation environment.


Conclusion

Project teams must develop a common sense plan to incrementally test and verify hardware and software together, right from the start of the project. Too often, project teams use a seemingly random approach to developing different types of software and try to run it using many different execution modes in parallel, just hoping one of them will work and prove that everything is ok. There is a great struggle today to decide how and when to deploy specific products for co-verification, simulation acceleration, emulation, and prototyping. The risk is too great to try to haphazardly mix and match tools late in the project. Engineers have nagging questions about whether emulation will really work and how fast it will go. They also wonder if the design will really fit into large FPGAs for a prototype, and if the prototype does run, whether it will be possible to debug it.

The ideal solution provides a single integrated system for logic simulation, simulation acceleration, and system emulation along with the concurrent debugging capabilities of both hardware and software. Advancements in co-verification will come by providing a smooth transition across these platforms with the right debugging tools for the job.

© Copyright 2005 Verisity Design, Inc. All rights reserved. Privacy Policy.