 |
 |

n the past, developers designed ASICs to solve specific problems using pure hardware solutions. More recently, higher levels of integration have produced complete system-on-chip (SoC) designs that now integrate hardware and software functionality in silicon. As a result, system-level verification requires the introduction of software components.
Since software and hardware are two different abstractions of a system, it makes sense to model the system using languages that best express these abstractions. In lieu of a future with a unifying system language, a mix of hardware modeling languages (VHDL and Verilog) and data modeling languages (C/C++) can be used to best do system-level verification of complex SoC designs.
Developers have used homogeneous HDL language testbenches very successfully to verify discrete hardware solutions, and they continue to be a popular solution for module testing by hardware designers. But this approach becomes cumbersome when a system-level verification is requiredespecially in an SoC where embedded processor cores are running software.
Large, monolithic HDL testbenches are difficult to manage and adapt when one is attempting to exercise and coordinate multiple hardware blocks, including interactions with software. Each test case may require a small change to the testbench, which results in multiple testbench configurations and HDL recompilations. The main disadvantage of this approach is the difficulty of using an HDL to create and check the large amounts of data required to do this type of testing.
Highly integrated systems, including processor core-based SoCs, blur the line between hardware and software. But system-level verification requires that both views of the design be verified, so it makes sense to use a software programming language to model data entities and an HDL to model physical entities.
Several via approaches to this sort of modeling are available. One approach is to create languages that incorporate both hardware and software requirements. Vera and the Verisity Specman e language are examples of this approach. Both provide a robust set of constructs that allow testbenches and tests to be written efficiently in a single environment. Hardware can be manipulated with HD-like syntax while data modeling and checking is done with programming-language types and methods. Coupled with co-verification tools like Eagle and Seamless, these suites provide a complete solution for system-level verification.
Another interesting approach is Co-designs Superlog language. In Superlog, C-like extensions for data modeling are added to standard Verilog. With a simulation environment that supports direct C interfaces, hardware engineers already familiar with Verilog can to ease into C. This could help minimize the learning curve that the hardware community faces in shifting to mixed-language verification.
Superlog also allows software engineers a means to cross the divide into hardware/software systems verification. Superlog offers the additional advantage of eliminating complicated PLI interfaces to C, which could increase simulation efficiency.
C and Verilog
Currently, however, the most widely used approach to verification is to combine C or C++ and Verilog/VHDL in a mixed-language verification environment. The QuickBench verification tool from Forte Design Systems (Formerly Chronology) employs this technique, as do most home-brewed solutions. Fortes proprietary Rave verification language, or C/C++, can drive tests in QuickBench. The basic approach involves a transaction-based interface between the C test and the HDL, in which atomic units of information pass to and from the hardware simulation via the HDL components connected to the design under test.
To make the most of the languages in use, examine each block in the design and determine the physical-layer protocol. That layer includes the number of pins, clocking and signal-timing requirements. An HDL component, called a transactor or bus functional model (BFM), needs to be designed to take care of these requirements.
The next step is to identify the transactions, including the passing of atomic data to and from the C test, which the transactor will perform. The data will be modeled in C. For simple interfaces, there may only be a single transaction type.
Suppose, for example, a simple serializer/deserializer serial-interface transactor needs to drive (or read) a Serdes port on a communications chip. The electrical protocol is satisfied by the HDL that will provide the functionality needed to serialize a data set, perform 8-bit to 10-bit encoding, provide a start character and clock the data onto the bus.
Note that this single transaction may take many simulation clocks to complete. For this application, the atomic data C provides is a cell containing multiple bytes of data. The transactor has no knowledge of the meaning of the cells data; it is generic and reusable. On the other hand, C interprets the cell as a header with routing information followed by payload. C, via strong data typing and complex structures, can layer any protocol on the cell that the application requires. Further, at a higher level of abstraction, C can know that a packet contains multiple cells and that a message contains multiple packets. This is how protocol stacks are built in real applications.
C also knows what cells have been created and where they are routed. If a design contains a data source and a data sink, we can create the source data within the C programdynamically if necessaryand predict the expected output. Data can be self-checked as it arrives at a sink.
The prediction may involve a transformation if the hardware is doing some data manipulation. This can be modeled in C and may already have been, as part of an architectural analysis. But this kind of dynamic self-checking in an HDL is clunky and inefficient, because there is no provision for run-time memory management, global data or pointers.
A more complex transactor example would be a BFM for PCI. In this case, a number of physical-layer transactions must be supported, such as read/write of bytes, words, long words for memory, I/O and configuration space. In addition, various burst modes and things like bus arbitration must be dealt with. The HDL BFM will need to support all of this.
On the C side, consider having a PCI Master emulate a CPU. Its possible to write standard C programs that access the PCI bus, just as a real program running on a processor would. Use a C++ wrapper class to convert C assignment statements to transactions that the PCI BFM can execute.
Consider the following code snippet, for example. Suppose you have a port, PORTA, located in PCI I/O space at 0x1000. The C program states:
PORTA = 0xFFFF;
int temp = PORTA.
Under the hood, the wrapper converts this to the following transactions that pass to the PCI BFM:
WRITE_IO_16(0x1000, 0xFFFF)
temp = READ_IO_16(0x1000)
This code could later be recompiled without the wrapper and run as is on the target processor.
In a mixed-language testbench, the HDL transactors for each I/O block send and receive data via a PLI/C interface layer. This layer also takes care of interprocess communications via shared memory between the C test process and the simulator. A shell program co-ordinates starting the simulator and C test, then takes care of test results, message logging and orderly simulation shutdown when errors occur.
So what are the pitfalls to mixed-language verification? The most commonly expressed concern is the learning curveboth hardware and software engineers must possess proficiency in multiple languages. The learning curve will likely become less of an issue as technology advances and the lines separating hardware and software blur.
The other major issue is debugging tools. Debugging environment problems as they occur is difficult. What is required are hooks in the simulators that would allow software debuggers to run in parallel with a simulation and provide breakpoint control so that both the simulation and the C program can be halted and debugged simultaneously.
Another problem is how to reliably interfacing C programs with simulators. Commercial tools provide robust interfaces via PLI/FLI or proprietary simulators that ensure that interactions between C and HDL are reliable and deterministic. Home-brewed environments, on the other hand, are rife with problems. These problems include hacked PLI/FLI interfaces and a lack of good software programming practices, which produces broken, non-reusable testbenches that are discarded at the end of the current project.
Intrinsix has successfully used mixed-language verification environments to do system-level verification of complex ASICs and SoCs. It recently completed a 200K-plus gate PCI bridge chip with multiple I/O blocks, including USB, IDE and MAC. The chip, which taped out in the first quarter, had multiple PCI masters that could concurrently arbitrate for the bus.
Intrinsixs first environment was a mix of Verilog and a C test that drove a PCI master BFM via a SoCket interface to the simulator. Transactors were built for each of the blocks, and they were driven via a static command queue imported by C into the simulator at startup. Because the C test was a single thread of control, the simulation would act as a block between bus transactions coming through the SoCket. This didnt permit multiple PCI BFMs to run concurrently.
This approach was later refined to provide concurrency on the C side via a multithreaded C++ interface. The transactors were reused with a slight modification to the PLI interface. Because the transactors were now being driven by their own C thread of control in the test program, data generation and checking could be done dynamically. This also allowed for direct synchronization of transactor operations on the C side.
Further, Intrinsix added callback facilities from the HDL to C to provide for things like interrupt processing in software. Any hardware event can be monitored to generate a call to a C function for further processing. This allows for back synchronization of the C test with specific hardware events at the timing resolution of the simulator. This capability eliminates the need for C to be timing aware-something at which it is not very good.
Intrinsix is using this approach to verify a fabric switch chip set. All the interfaces now have transactors. C++ traffic generators with random data capability have been added. Intrinsix also created a number of C models of the hardware, using Fortes Cynlib class library, in order to have design stubs as the register-transfer was under development.
The Cynlib models drive transactors in the testbench, mimicking the interfaces for the actual design blocks. As such, it permitted the placement of system testbench and tests parallel with the design effort, thus saving time in the schedule. Its possible to run these models in parallel with the actual RTL as checkers, further automating the test process. Intrinsix is also looking at using SystemC for similar modeling tasks.
The ever-increasing complexity and software content of SoC designs is forcing the need for full-system verification of hardware and software before silicon is produced. A mixed-language approach can offer many advantages; it can capitalize on the strengths of HDLs and software programming languages to best match the level of system abstraction that needs to be verified.
Bob Morasse is technical manager, Intrinsix Corp. (Westboro, Mass.).
|