Connect a ARM Microcontroller to a FPGA using its Extended Memory Interface (EMI)
Although there is the versatile and powerful ZYNQ extensible processor-centric architecture with its on board dual-core Cortex-A9 ARM processor devices, sometimes it is necessary to use a standalone micro-controller in combination with a processor-less FPGA. Of course a standalone micro-controller can also be used in combination with a ZYNQ FPGA.. This note provides a way to hook a FPGA to an of the shelf available ARM micro-controller. The FPGA can use the micro-controller as process controller or as extended multi-peripheral (USB, LCD, Keyboard, and etcetera) device. The micro-controller mostly uses the FPGA as pre-processing high-speed, high performance calculation extension.
An FPGA is primary used for computationally intensive, high-speed and/or parallel processing tasks while the ARM micro-controller is widely used due to its versatility, many manufacturers implement it as the core for their applications (Including he ZYNQ family of devices). Because ARM devices are so widely used across the processor sector there is a variation of operating systems available. An application that caused this note to be written was a video application using an FPGA as high speed – parallel video processing engine and a dedicated ARM micro-controller as human interaction interface. The solution provided is to use one Chip Select area of the micro-controllers External Memory Controller (EMC) in SRAM mode and connect this to the FPGA. Figure 1shows the setup of an example video design.
Figure 1: Micro-controller – FPGA video application.
The FPGA connects via the External Memory Interface (EMI) to the ARM processor. To prove this concept some design decisions were taken:
- Use on the market available micro-controller hardware.
- The Phytec phyCORE-LPC3250 development board was chosen.
- Use an available Xilinx Development board.
- Virtex-6 LM605, 7-Series KC705 or VC707 boards.
- A board with a processor-less FPGA is chosen because the connection between the external processor and FPGA must be proved.
- A ZYNQ connecting to it's FPGA Block-RAM is topic of another article.
- Use an OS.
- The Phytec development system comes with a Linux port.
- The obvious choice was thus to go for Linux in stead of writing code on the bare metal of the ARM processor.
With the choice of the Phytec board came the NXP LPC3250-A9 micro-controller. The Phytec board data can be found on: www.phytec.com.
The details of the micro-conroller can be obtained from: www.nxp.com The LPC3220/30/40/50 embedded micro-controllers are designed for low power, high performance applications. NXP achieved these goals using a 90 nano-meter process to implement an ARM926EJ-S CPU core with a vector floating point co-processor and a large set of standard peripherals.
The NXP implementation uses a ARM926EJ-S CPU core with a Harvard architecture, 5-stage pipeline, and an integral Memory Management Unit (MMU). The MMU provides the virtual memory capabilities needed to support the programming demands of modern operating systems. The ARM926EJ-S also has a hardware based set of DSP instruction extensions, which includes single cycle MAC operations, and hardware based native Jazelle Java Byte-code execution. The implementation has a 32kB instruction cache and a 32kB data cache. The LPC3220/30/40/50 includes a whole set of peripherals and memory support:
- 256 kB of on-chip static RAM,
- NAND flash interface,
- External bus interface (EMI) supporting SDR, DDR SDRAM and static devices.
- Ethernet MAC
- LCD controller that supports STN and TFT panels
- USB 2.0 full-speed interface
- Seven UARTs
- Two I2C-bus interfaces, two SPI/SSP ports, two I2S-bus interfaces.
- Two single output PWMs, a motor control PWM
- Six general purpose timers with capture inputs and compare outputs
- Secure Digital (SD) interface
- 10-bit Analog-to-Digital Converter (ADC) with a touch screen sense option.
The interesting peripheral for this FPGA application is the processors External Memory Interface. The EMI is controlled by the External Memory Controller (EMC), an ARM PrimeCell MultiPort Memory Controller peripheral. The EMC is an Advanced Microcontroller Bus Architecture (AMBA) compliant peripheral, Figure2.
Features of the EMC are:
- Dynamic memory interface support including Single Data Rate and Double Data Rate SDRAM.
- Supports mobile SDRAM devices with 1.8 V I/O interface.
- Asynchronous static memory device support including RAM, ROM, and Flash, with or without asynchronous page mode.
- 2k, 4k, and 8k row address synchronous memory devices.
- Typically 512 Mbit, 256 Mbit, and 128 Mbit devices.</p>
- with 4, 8, 16, or 32 data bits per device.</p>
- Low transaction latency.
- Read and write buffers to reduce latency and to improve performance.
- 8 bit, 16 bit, and 32 bit wide static memory support.
- 16-bit and 32-bit wide SDRAM memory support.
- Four chip selects for static memory devices.
- Two chip selects for synchronous memory devices.
- Static memory features include:
- Asynchronous page mode read
- Programmable wait states
- Bus turnaround delay
- Output enable and write enable delays
- Extended wait
- Power-saving modes dynamically control clock and clock enable to SDRAMs.
- Dynamic memory self-refresh mode controlled by software.
- Separate reset domains allow the for auto-refresh through a chip reset if desired
Figure 2: EMC block diagram.
The External Memory Controller (EMC) has four memory areas where static memory can be connected, and an FPGA can be seen as static memory. The FPGA - micro-processor connection uses for this design the memory range of chip select CS2 (Figure 3). A single FPGA will occupy only a small amount of memory in this address space. When the processor read and/or writes to this EMC_CS2 address space it accesses the contents of registers and memory blocks (FF registers, BlockRAM and/or distributed memory) in the FPGA. Read and write operations from the EMC to static memory a fairly simple and straight forward. Figure 4 shows the waveform of a read operation and figure 5 shows the write operation. In case it might be needed, the EMC controller contains a register set allowing to control access delays for the static memory. For the description an use of tehse registers consult the LPC3250 User Guide.
Since for the demo/test design only two Block-RAMs are used the address decoding is not very fine tuned. The address space to access the Block-RAM appears several times in the CS2 address block of the EMC. When the FPGA is effectively used in an application as co-processor, pre-processor, high-speed calculation or high-speed communication engine for the ARM micro-controller it is most likely that different Block-RAM and separate registers are used and need to be addressed. Then it will be necessary to fine tune the addressing of the FPGA from the micro-controllers EMC.
Figure 3: Cut-out of the External memory map from the LPC3250 memory map.
Figure 4: EMC static memory read operation.
Figure 5: EMC static memory write operation.
In case it is needed, the EMC controller contains a full set of configuration registers for every possible type of memory that can be connected to the EMI interface. It is thus possible to set read and/or write delays, bus turn around times and etcetera.
To get the finesses of this, please read the LPC datasheet and User Guides.
The interface in the FPGA is very straight forward. It consists of a bidirectional 32-bit data bus and a unidirectional address and control bus. From the micro-controllers address bus only these address bits are used that are needed for addressing the application in the FPGA. A block diagram of the ARM interface in the FPGA is shown in Figure 6.
- The address interface in the FPGA makes sure that the combination of the address bits and control bits (read, write, enable, interrupt, and etcetera) make surer the correct peripheral in the FPGA gets accessed in the right direction, read or write to or from the ARM.
- The data part of the interface is at the IO level a data pass through and internally it can be seen as a address bus, read and write controlled set of multiplexers.
Figure 6: FPGA ARM interface block diagram.
The demonstration design contains two Block-RAM components, one used to write to and one used to read from. The other access ports of both Block-RAMs are connected together and when the Block-RAM for write is completely full, data is transferred to the read Block-RAM. When the read Block-RAM at its turn is full data can be read from it, Figure 7. Correctness of the read and write operation can easily be checked this way. Of course, a real life application will have probably multiple Block-RAM. Distributed memory and normal FF registers that can be written and/or read via the EMI interface of the micro-controller.
Figure 7: Design to show ARM - FPGA read and write.
Very important is the connection of the LPC3250 component and the FPGA on PCB board level.
- The micro-controller External Memory Controller voltage can be 1V8, 2V5 or 3V3 as shown in figure 8 . The EMC must run in 3V3 voltage mode to connect to the FPGA because it is used in SRAM mode.
- All IO of the micro-controller are LVCMOS compatible.
- The IO of the FPGA can be used in different voltages and different IO standards, but LVCMOS must be selected as IO-standard.
- Virtex-6 runs at LVCMOS 2V5.
- Level translation components will be needed to be able to let the micro-controller and FPGA exchange data.
- 7-Series runs at: LVCMOS 3V3 in HR IO-banks and 2V5 in HP IO-banks.
- For HR IO, level translators will not be needed.
- For HP IO level translators are necessary.
- Virtex-6 runs at LVCMOS 2V5.
In order to let the micro-controller and the FPGA exchange data it is in many cases necessary to use level shifting components. Figure 9 shows a schematic (figure 10a photo) of the setup.
Figure 8: LPC3250 EMC power and operating supply voltages.
Figure 9: Connection between LPC3250 and FPGA using level shifters.
Figure 10a: Photo of the realized setup.
REMARK: The schematic figure 9 shows a circuit using Texas Instrument level shifter components but this is not a must any good level shifter component can be used.
Make Linux work on the Phytec board.
The following description describes how to build and port Linux onto the Phytec board and assumes that the host computer runs a Linux distribution, as Ubuntu. The host computer is connected to the Phytec board via a serial cable (at the side of the PC the RS232 cable is probably converted to USB and a USB driver translates all RS232 communication for the PC).Firstly your own version of Linux needs to compiled, to do this a PC running Linux or at least a PC equipped with a virtual machine running Linux is needed.
The Linux Target Image Builder (LTIB) will be used to generated the embedded kernel. LTIB, the operating flow is shown in figure 11, is a tool used to develop and deploy Board Support Packages (BSP) for a number of embedded target platforms including PowerPC, ARM, and Coldfire. It can be found and downloaded at: http://bitshrine.org/ltib/.
Figure 11: LTIB Flow Diagram.
LTIB will not only compile the kernel but also supply a root file system, an additional boot loader (Das U-BOOT) and further everything you need to write your own applications. To start programming, a compiler is needed and since it is not included in with LTIB it needs to be downloaded from the WWW. Recommendation: Download the command line compiler from CodeSourcery. It's free, and other tried/tested compilers were badly documented or not compatible with the ARM926EJ-S core in the NXP LPC3250 on the Phytec development board. Following pages provide a tutorial to build a Linux kernel for the LPC3250 on the Phytec PhyCore board.
REMARK: In the commands that should be typed at the command line heave the ComicSans MSfont, that way they can easily be recognized.
Install LTIB on the host:
- Make sure to operate in the projects directory where the kernel will be made. Create a sub-directory for LPC3250 related development and switch to the new directory:
mkdir lpc3250 cd lpc3250
- Download the netinstall script:
./lpc3250> wget http://www.bitshrine.org/netinstall
- Run the netinstall script:
./lpc3250> perl netinstall
- For the LTIB install, “sudo” permissions to execute rpm commands as root without a password are required. To enable this run visudoas root.
./lpc3250> sudo /usr/sbin/visudo This allows editing of the “sudoers”file. Enter the line: <username> ALL = NOPASSWD: /bin/rpm, /opt/ltib/usr/bin/rpm Restart the install process by executing again the “perl netinstall“ script. The setup will ask for a install path, provide the full path as: /home/<username>/”Path”/lpc3250/
- Hint: If the “netinstall” script does not work automatically open another terminal window, open the “perl netinstall” script with an editor and execute every instruction by hand. This can be done by typing the following commands:
cd /home/<username>/lpc3250 ~/lpc3250> vi netinstall
- Still problems? Pay a visit to: http://www.bitshrine.org/ltib/resources-download
- Normally the install runs without problems and LTIB is ready.
- Hint: Modifying the LTIB configuration is done by:
./lpc3250/ltib qs> ./ltib ‐ --configure
- A menu will pop-up, follow the instructions to:
- Select the platform.
- Choose the Phytec 3250 board.
- With the NXP LPC32XX SoC from the list.
- Select Exit and Yes to save the new configuration.
Build U-boot, Linux kernel and root file system:
- LTIB automates building U-Boot, Linux kernel, and root file system. LTIB allows configuration of the boot loader, kernel, and installed packages through a menu driven system.
- Begin the build process by returning to the shell window used to install LTIB.
~/lpc3250> cd ltib‐qs ./lpc3250/ltib qs> ./ltib <pre> * A menu with a lot of options will pops-up. The recommendation is to start experimenting with the settings. The settings made in the menu are very specific and depending on the application. ** The settings that worked for this test application are given in table 1.
|System features||[*] cache target rpms|
|Target C library type||(X) glibc|
|C library package||(X) from toolchain only|
|Toolchain component options||[*] libc shared libraries
[*] c++ shared libraries [*] libgcc*.so*
|Toolchain||(X) gcc-3.4.5-glibc 2.3.6 (soft_float)|
|Enter any CFLAGS for gcc/g++||-fsigned-char-msoft-float-O3|
|bootloader choice||(X)u-boot1.3.3 for the Phytec3250 board|
|u boot flags||<empty>|
|kernel||(X) Linux 22.214.171.124 for LPC3250 / Phytec3250|
|Always rebuild the kernel||[*] (checked)|
|Produce cscope index||[ ] (unchecked)|
|Include kernel headers||[ ] (unchecked)|
|Configure the kernel||[ ] (unchecked)|
|Leave the kernel sources after building||[*] (checked)|
|Package list||Check only:
[*] busybox [*] module dependencies [*] mp3play [*] mtd utils [*] Skeleton base files
|Target System Configuration Options Check only:||[*] start networking
[*] start syslogd/klogd
|Target Image Generation Options||Target image: (NFS only)|
- Select Exit and Yes to save the new configuration.
- LTIB will start to compile the custom kernel this will take a while.
- Hint: get a cup of coffee.
- It is possible that a menu pops up while compiling, this means that some options are left unchecked or are checked. Example: The option to configure the kernel is left checked.
- Explore with the options, but for the first time it is maybe better to leave all options a default.
- When all goes well the compile process is done with the message “Build Succeeded”.
- Hint: it's possible that the process fails. Restart the LTIB configuration process to adjust the settings.To restart the LTIB configuration menu, type:
~/lpc3250/ltib‐qs> ./ltib ‐‐configure
Note that LTIB will only enter the configuration menu the first time after install when typing ./ltib a the prompt. After the first run, typing ./ltib at the prompt will rebuild modified source. It is thus necessary to type ./ltib ‐‐configure in order to modify the configuration of LTIB.