Basics of core-based FPGA design: Part 4 – Implementing a design

R.C. Cofer and Ben Harding

August 22, 2011

R.C. Cofer and Ben Harding

The C programming language was selected to implement the PowerPC software program. A few programming considerations to keep in mind for embedded development include:

1) Use the static syntax to control variable visibility
2) Use the nonvolatile syntax to prevent the compiler from optimizing out key variable
3) Code to reduce branching since stalls affect efficiency
4) Maintain an awareness of the state of stack usage
5) Disable interrupts when validating boot code
6) Include comments to clarify code intent, and to identify critical design factors and exceptions
7) Use null interrupt service routines (ISRs) for any unused interrupts

One of the biggest traditional design challenges involves bringing up a new hardware board for the first time. The challenges associated with this process can be significantly reduced by initially developing and verifying software on a known-good evaluation board platform.

Having access to a target evaluation board in advance of the access to the final hardware board allows progress to be made and increases confidence in the functionality of code developed before the final target board is available.

Access to a verified hardware platform can also be invaluable during board verification since it can provide a stable platform for operational comparison. The process of booting the target software within an FPGA embedded processor begins once the FPGA has been successfully configured.

In a well-designed system, the processor will be in a defined nominal state with the processor held in reset. Once the processor’s reset is released, the processor will jump to the reset vector location. The reset vector is a defined memory location, “0xFFFF FFFC” in the PowerPC. The instruction at this location must be an unconditional branch to the first location of the boot code.

Most FPGA embedded processors have their boot code loaded in memory within the FPGA during the device configuration process. The boot code program is a non-compressed routine that contains the code for initializing the processor and then copying the application code to its runtime location within memory.

The first task of the boot code is to initialize registers to place the processor in a known state and defined memory map. This includes clocking speeds, execution mode, and other related processor-specific items requiring definition, such as the memory interface.

The PowerPC core is in big-endian mode by default after exiting reset, thus boot code must be in big-endian format. Program execution begins after a jump to the location in memory where the boot code is located. Before jumping to the application code, the boot code must set up the C environment. Once the C environment is configured, the boot code jumps to the boot-loader, and completes the boot-up sequence by performing a self-test to rule out potential hardware failures.

The memory contents are then placed in a known state, before copying operational code and jumping to the beginning of the application code. Before the operational code copy procedure occurs, the boot-loader checks for potential updates. If an update is available, the boot-loader will erase the nonvolatile area of memory containing the application code and store the new version. It will then copy this new code version to its specified runtime location. A related application note is Xilinx XAPP642 Relocating Code and Data for Embedded Systems.

The boot code is separate from the application code to protect the system from corruption of the boot code. Corruption of the boot code will render the system incapable of booting. Code updates may occur via updates through interfaces such as Ethernet or RS-232. A generalized board bring-up process is summarized in the following list.

Board Bring-Up of the FPGA Embedded Processor 

1) FPGA initialized from external nonvolatile FPGA configuration source
2) Processor powers-up in reset mode
- On release of reset, processor vectors to the reset code location
– May be either external nonvolatile memory or a volatile memory block on the FPGA loaded during FPGA configuration process
3) Initialize processor (typically written in assembly)
4) Set-up higher level language environment and jump to boot-loader section of boot code
5) Perform hardware integrity test including memory and other hardware that could affect processor operation
6) Update application code if newer version is available
7) Copy program from source to its runtime location
8) Jump to application code
9) Initialize RTOS and set-up BSP
10) Kick-off scheduler

Debugging can be accomplished by supporting access to signals and nodes internal to the FPGA. Signal test headers and signal access are discussed in the device-level and board-level design decision chapters. Since the 405 processor uses a 32-bit bus, at least 36 lines should be brought out to a test header. This supports parallel access to the processor bus and some control signals.

The test header should also include several grounded pins to support simplified test equipment connection. LEDs and switches may be included to help debug the design. Signal and internal node access may also be supported through a JTAG ChipScope Internal Logic Analyzer implementation. Implementation of a second JTAG port may allow additional 405 PowerPC debug capabilities such as trace capability. Implementation of an internal logic analyzer does require some FPGA internal resources to implement.

Conclusion
The implementation of processors embedded within an FPGA device can be a challenging and complex process. Careful consideration of critical system design elements can help streamline this process. Table 14.2 below provides a high-level FPGA embedded processor design checklist.

Table 14.2. Processor checklist
Ultimately, the implementation of an embedded FPGA processor design involves every aspect of system-level design with a higher level of flexibility. Since every aspect of the design implementation may be specified by the design team, there is a higher level of flexibility throughout the design cycle than is encountered with conventional discrete processor design.

The design team is responsible for the evaluation, selection and implementation of each functional element within the FPGA device. The design team has unprecedented freedom in the implementation of the design with the option to implement functionality within either the hardware or software domain.

Even late in the design process, the design team can repartition or reconfigure the design architecture and adjust critical design elements if the system performance benefits justify the required effort to implement the design changes. With the correct preparation, an organized and disciplined team can implement complex, customized designs efficiently.

To read Part 1, go to "Core types and tradeoffs"
To read Part 2, go to "System design considerations"
To read Part 3, go to "Picking the right core options."

Used with permission from Newnes, a division of Elsevier. Copyright 2006, from “Rapid System Prototyping with FPGAs,” by R.C. Cofer and Ben Harding. For more information about this title and other similar books, please visit www.elsevierdirect.com.

RC Cofer has almost 25 years of embedded design experience, including real time DSP algorithm development, high speed hardware, ASIC and FPGA and project focus. His technical focus is on rapid system development of high speed DSP and FPGA based designs. He holds an MSEE from the University of Florida anda BSEE from Florida Tech.

Ben Harding has a BSEE from the University of Alabama, with post-graduate studies in DSP, control theory, parallel processing and robotics. He has almost 20 years of experience in embedded systems design involving DSPs, network processors and programmable logic.

< Previous
Page 3 of 3
Next >

Loading comments...

Most Commented

  • Currently no items

Parts Search Datasheets.com

KNOWLEDGE CENTER