Increased device integration has meant that for several years chip makers have been building ASIC system chips with one or more microprocessors combined with memory and other functions such as signal processors or communications protocols. However, devices that combine a processor, memory and a PLD have only recently appeared on the market. Such programmable system chip (PSCs) give developers several advantages over nonprogrammable ones: First, they avoid the costly and lengthy implementation cycles of an ASIC; second, they allow for a less rigorous pre-implementation verification cycle because it costs less when problems are found after the chip is programmed.
Using dedicated hardware to boost the real-time performance of embedded systems is a common practice. Now, with the introduction of PSCs, we will see more widespread adoption. In the new era, many software engineers will learn how to use the inherent parallelism of hardware to boost performance of timing-critical software functions.
The difference between software and hardware design is like the difference between driving and flying. A car traces a linear path through a planar space; reaching the destination quickly and safely requires skills in operating the car as well as detailed knowledge of the vicinity. But an airplane operates within another dimension, which adds altitude, pitch and yaw to the degrees of freedom the pilot must manage. The cockpits of the car and the airplane are similar, but no one who drives a car would consider flying a plane without special training.
Likewise, software traces a sequential path of instructions through a complex graph of machine code. Developing fast and reliable code requires skills in programming languages, compilation and debugging tools, and detailed knowledge of the application space. Hardware processes multiple paths of information in parallel, adding the dimensions of cycle time, data latency and pipelining to the degrees of freedom. The advantage of the PSC approach to hardware design is that, unlike flying, a software engineer can learn hardware design without fear of serious physical (or fiscal) injury.
Over the next few years, software developers will benefit from improved PSC architectures and improved development tools. The new "autopilots" for hardware design will automate some of the decisions required, making the transition from software developer to PSC developer much easier.
Until then, software developers with some hardware knowledge can still benefit from PSCs by learning to overcome the differences between designing software for processors and designing programmable logic hardware. These differences include learning hardware design concerns, including identifying and using its inherent parallelism; learning a new language, or learning how to use the language they already know, for hardware design; learning to use new design tools for design verification and logic synthesis; and learning how to debug the design once it's in place.
As with flying, the first problem is to get off the ground. The basic problem for developers of embedded software is designing software that will run fast enough in a real-time environment. To do this they need to design operations that can be completed quickly. If this is not possible in software, then they will need dedicated hardware to improve the function's performance.
Software developers must have at least some knowledge of hardware design in order to use a PSC. The key to this knowledge is understanding that they are shifting design bottlenecks from inherently serial software operations to inherently parallel hardware functions and understanding how to take advantage of this parallelism. Once the software bottleneck has been identified, the system developer must then identify which operations can be done in parallel vs. which must wait for the results of other operations or calculations.
After identifying software bottlenecks that are candidates for hardware implementation, the system designer must determine the feasibility of a hardware implementation. The sense of what is feasible to implement in hardware is one of the first stumbling blocks to overcome for those not familiar with hardware design.Interface needs
Beyond the algorithm implementations, the interface requirements must also be designed. The software requires a procedural interface to the hardware, such as memory-mapped I/O or an interface to the processor's system bus. If the algorithm requires access to processor memory, then a memory interface must also be developed. The PSC vendor will probably supply solutions to these common problems. When evaluating which PSC to use, make sure that the software-hardware interface meets the needs of your design.
After arriving at a basic hardware design, the software designer must then describe the hardware implementation for the logic synthesis tool that will feed the device vendor's programming software. The most popular logic synthesis tools start with a description at the register transfer level (RTL) abstraction, which means that every operation has explicit hardware timing. More specifically, it means that every storage element (flip-flops or registers) is described explicitly in the RTL description and every register is loaded synchronously with the rising or falling edge of a clock signal.
The standard design language is an HDL, either VHDL or Verilog. These languages are variations of Ada (VHDL) or C (Verilog) with constructs to handle parallelism, design hierarchy and the wide variety of data types that are available in hardware. There are many books on the use of VHDL and Verilog for hardware design.
One industry trend that will make it easier for software developers to design hardware is the nascent support for the well-established software design languages (C, C++ and Java) for hardware design. Once support for these languages is viable, software engineers will not have to learn a new language. However, they will still need to learn how to use the familiar language for hardware design.
Tools are available for using software languages for hardware design, but the paradigm for using these tools continues to evolve, and neither a standard coding style nor a standard design abstraction exists.
At least four paradigms are in use in commercial or proprietary tools, all of them involving restrictions on how the software language may be used so that the result will be a feasible hardware implementation. Most of them prohibit the use of common C constructs, such as function pointers, which are difficult to implement in a finite hardware implementation.
In order of increasing levels of abstraction, these four methodologies are:
- Paradigm 1. This uses a restricted subset of RTL for single-clock designs with the restriction that all hierarchical modules have registered outputs. This paradigm has the advantage of being able to yield very high-performance simulation of the design. However, the restrictions of single-clock design with the strict adherence to registered outputs for all leaf-level modules means that some designs cannot easily be described in this paradigm.
- Paradigm 2. Called the RTL paradigm, this uses a Verilog-like overlay (in the form of a C++ class library) to implement RTL designs using C++. This paradigm mimics the common usage of the standard HDLs, but with a more familiar syntax. One advantage of this approach is that the simulator is built into the C++ class library, and so RTL simulation is essentially free.
- Paradigm 3. This is known as the architecture level, where the storage requirements of the algorithm are "inferred" from the context. This provides an abstraction slightly above RTL, since no explicit clocking is required.
- Paradigm 4. This is the behavioral level. It attempts to automate the scheduling of parallel operations to remove the burden of identifying explicit storage elements from the software engineer. The behavioral paradigm has been around for a long time with VHDL, Verilog and other language input, but has not found general market acceptance. However, tools that support this method are often successful for implementing efficient digital signal processing algorithms.
Over the next two or three years, software language support for hardware design will mature and the design community will probably settle on one or two of the four paradigms. The RTL one has tremendous momentum with wide acceptance for VHDL-and Verilog-based design. Paradigm 4 has great potential to succeed in certain applications where the parallelism of the operations can be exploited in a few standard hardware architectures.
After coding the design in the language of choice, the designer must prove that the design works as expected. This process is variously known as verification, validation, simulation, emulation, test or debug. For clarity, we adopt the following definitions: Verification is the process of proving that the design functions correctly; simulation occurs before hardware exists; debug occurs after hardware exists.
The essential problem in verification is that before the programmable logic can be built, the designer must demonstrate that the new combination of software and programmable logic performs the same function that software alone performed and that the combination operates fast enough to meet the real-time requirements. Simulation is the first point in the design flow where developers discover whether this is, in fact, the case.
Hardware designers use VHDL and Verilog simulators to verify their designs. Simulators work very well for validating hardware independent from the software of the system. However, simulating the software/hardware system is more complex, and requires significant effort interfacing the software to the programming interface of the simulator or the purchase of a software/hardware co-verification tool.
Perhaps the greatest advantage of adopting a programming language design paradigm rather than an HDL paradigm comes from the relative ease of interfacing the software to the hardware simulation. The software developer can use the hardware simulation capabilities inherent in the chosen paradigm and can use
familiar C/C++ debuggers to diagnose problems, reducing tool cost and improving productivity. After simulation, the developer has a language description of the design that simulates correctly. Now the developer must get from the language description to the programming files for the PSC.
In the standard programmable-logic hardware design flow, a synthesis tool, such as the Synplify Pro software, compiles an HDL description of the design into a netlist that specifies the interconnections among the programmable elements of the device. The netlist then feeds into the programmable logic vendor tools that map the circuit elements to specific circuit locations within the device and interconnect the elements as specified by the netlist and other designer controls. The resulting programming file can then initialize the device to its specified operation.
If the PSC developer chooses one of the C/C++ paradigms, a good synthesis tool and the programmable logic vendor tools are still needed. Today, the tools that support the C/C++ paradigms all compile the input into a VHDL or Verilog RTL design that feeds into a commercial synthesis tool.
For software developers who are unfamiliar with designing hardware, ease of learning and ease of use are the most important considerations for choosing a synthesis tool.
The Synplify Pro software was designed to have a short learning curve, but also to have the power to produce excellent results quickly, especially for complex designs.
Verification can never be complete until the software operates on the real hardware. Software developers have tools to help them debug in the real system, but the software/hardware interaction is one of the most probable causes of problems. The software developer would like to have a way to debug the hardware in the same way software is debugged. Like the C/C++ hardware design paradigms, in-system hardware debug tools are in a nascent form. The basic technique of these tools is to synthesize a simple logic analyzer that resides in the programmable logic together with the design. The developer can control the logic analyzer through a standard interface.
The technology for PSCs has nearly caught up to the need for completely programmable systems. A microprocessor with memory fits in a small portion of an affordable chip. In the rest of that affordable chip, enough programmable logic fits to implement a reasonably complex function. The performance of programmable logic is high enough that a reasonably complex function will operate considerably faster than an equivalent software algorithm. Finally, programmable logic synthesis and the vendor place-and-route tools have matured to the point that they are easy to use, reliable and give good results.
Over the next few years, the PSC design methodology will mature to the point that they will be widely used for system design. The problems surrounding design language paradigms will converge to a solution that inherently supports verification of mixed software/hardware systems and the debug support for hardware-accelerated software algorithms will support source-level, in-system debugging of hardware.
At that point, the embedded system developer can really take flight.