Implementing ARM Cortex-M processors in FPGAs can be a great way to take advantage of the flexibility and configurability of FPGAs while leveraging the software and toolchain support of the popular ARM architecture. Here are some tips on how to effectively implement Cortex-M cores in your FPGA designs.
Selecting the Right Cortex-M Core
The first step is choosing the right Cortex-M core for your application. The Cortex-M family includes small, low-power cores like the Cortex-M0/M0+ up to more powerful options like the Cortex-M7. Consider performance requirements, power constraints, and software needs when selecting a core. The smallest Cortex-M0/M0+ cores are good for simple, low-power applications while the M4 and M7 support DSP instructions and floating point for more complex software. Consult the ARM product literature to select the optimal core.
Obtaining the RTL Code
ARM offers RTL code for most Cortex-M cores either as synthesisable Verilog/VHDL or as a hard macro. Hard macros deliver the best performance and smallest area but are less flexible. Synthesisable RTL allows more customisation at the expense of larger size. The RTL code is available through the ARM DesignStart program or various third party sources. Be sure to consider factors like cost, customisation needs, and toolchain support when choosing the format of RTL code.
Integrating the Processor into the FPGA Design
With the RTL code in hand, the Cortex-M core can be instantiated in the FPGA design like any other module. Pay close attention to the port connections specified in the RTL code or macro documentation. Key interfaces that need to be hooked up include the system bus, peripheral bus, interrupts, debug connections, and clocks/resets. Make sure to follow any guidelines provided by ARM regarding clock speeds, resets, and connections for proper operation. Double check that all necessary ports are wired up correctly before synthesizing the design.
Configuring Memory and Peripherals
The processor will need associated memory and peripherals to be useful. Small programs and data can be stored in on-chip block RAM connected to the bus. Larger code can be implemented using a memory controller attached to off-chip FLASH or RAM. Various peripherals like UARTs, timers, GPIO etc. can also be connected to the bus. Make sure to size block RAMs appropriately and parametrize any memory controller or peripheral IP correctly for your system. Proper configuration is key to utilizing all of the Cortex-M’s capabilities.
Verifying the Hardware Design
Thoroughly verify the synthesized hardware design containing the Cortex-M core before progressing to the software stage. Run simulations exercising all key interfaces, stimulus cases, and corner cases. Verify proper sequencing during reset, clock interactions, bus transactions, and interrupts. Use a bus functional model to verify connectivity to peripherals. Identify and fix any issues with the RTL code or connections to avoid problems when developing firmware. Good verification practices at the hardware stage will save time later.
Developing Firmware with the ARM Toolchain
One of the major benefits of using a Cortex-M processor is the ability to utilize the extensive ARM software development tools. The ARM Compiler toolchain allows developing firmware in C/C++ and assembles/links it efficiently for the target core. Make sure to obtain a compiler version that supports the specific Cortex-M variant implemented in hardware. ARM also provides a CMSIS library with headers and peripherals drivers to simplify software development. Starting with the ARM tools and libraries accelerates creating reliable firmware.
Debugging with a JTAG Interface
Debugging both hardware and software is easier with the joint test action group (JTAG) interface supported by all Cortex-M processors. Connect the JTAG port on the FPGA to a debugger hardware module or debugger IP core. ARM’s CoreSight technology built into Cortex-M enables advanced run-time debugging features using JTAG, like breakpointing and single-stepping firmware. Investing in a good JTAG debugging solution is worthwhile for any serious application development using Cortex-M cores.
Validating the Full System
After verifying the hardware and developing initial firmware, the full FPGA system with integrated Cortex-M core can be validated. Exercise the full range of functions based on the intended application to uncover any issues. Stress test border conditions like maximum specified clock speeds. Optimize firmware performance using profiling tools and the compiler settings. Having a solid validation methodology for the complete hardware plus firmware system is imperative before deploying to a production environment.
Utilizing a Microcontroller for Prototyping
To accelerate prototyping firmware and software, first develop and debug on an external low-cost Cortex-M development board or microcontroller. ARM MCUs share a common architecture with FPGA-based SoCs. Developing software early on real silicon enables verifying key functionality before the FPGA hardware is finalized. Make sure to use the same Cortex-M core variant and clock speed for the most applicable firmware prototyping. Starting firmware development in parallel reduces project schedule risk.
Meeting Timing Closure and Fmax Goals
Using a processor soft core in an FPGA introduces timing challenges not present with other logic. The large core size and many synchronizing clock domains can make meeting timing difficult. If having issues with fmax after synthesis, consider using a smaller or simpler Cortex-M variant. Optimize the RTL code and constraints for best results. In some cases, a hard macro with optimized layout may be required to realize maximum clock speeds for fast processors like Cortex-M7. Balance timing closure with processor performance requirements.
Reducing Logic Utilization
In addition to timing, large processor cores can consume significant FPGA logic resources. If struggling to fit the design due to high core utilization, optimize the RTL code to disable unneeded features or peripherals. Switch to a smaller Cortex-M core variant if code size allows. Update FPGA constraints to emphasize area reduction during synthesis. In extreme cases, move to a larger FPGA package or family to obtain more logic cells. Employing good optimization techniques is key to reducing logic utilization.
Mitigating EM and Environmental Issues
FPGA and ASIC implementation brings challenges like electromagnetic interference (EMI) and environmental reliability not faced with microcontrollers. Take care to mitigate EM emissions from the high-speed core using proper PCB stackup and layout techniques. Avoid excessive radiation which can corrupt operation through configuration scrubbing or other mitigation methods. Cortex-M cores contain built-in error correcting code (ECC) memories to improve reliability that may need custom test bench stimulus to fully verify in simulation.
Leveraging Reference Designs
To accelerate the implementation process, leverage existing ARM and vendor Cortex-M reference designs for FPGAs. These provide working examples of optimal core instantiation, memory/peripheral integration, I/O connectivity and more. Studying reputable reference designs avoids re-inventing established implementation techniques. They serve as great learning tools for new users and helpful starting points for even experienced hardware engineers new to Cortex-M cores.
Conclusion
Implementing ARM Cortex-M processors in FPGAs opens up exciting design possibilities. Following these tips will help make the process smooth and successful. Carefully selecting the right core variant, procuring the optimal RTL source, verifying the hardware design, utilizing the ARM software toolchain, debugging with JTAG, validating the full system, prototyping firmware early, meeting timing closure, reducing logic utilization, mitigating reliability issues, and leveraging available reference designs will enable effectively harnessing the flexibility of FPGAs with the software ecosystem of the ARM architecture.