February 6, 20089 minutes
Overview
In the previous example, we created a project using the BSB and all of the work related to the hardware design was done by the BSB. In this example, we will create the same simple project, but this time we will add the GPIO for the LEDs manually. This way we will learn the process of adding extra peripherals to our design and we will also better understand the hardware design features of XPS.
This tutorial contains screenshots to guide you through the entire implementation process. You can click on the images to view a higher resolution when necessary.
Are you using EDK 10.1?
Try the updated version of this tutorial based on the Virtex-5 FPGA on the ML505 board: Manually Add a Peripheral to a Project
Create the Basic Project
Follow these steps to create the basic project:
RS232_Uart_1 and DIPSWs_4Bit ticked and un-tick everything else.
plb_bram_if_cntlr_1 and click “Next”.
RS232_Uart_1 for both STDIN and STDOUT. The Base System Builder can produce sample software applications to run on the PowerPC and test the memory and peripherals. For this project we will not need them as we will create our own. Un-tick “Memory Test” and “Peripheral Test”. Click “Next”.
Create a Simple Application
Now that the basic project is made, we can create a simple software application to run on the PowerPC to test the DIP switches.
Default: ppc405_0_bootloop. The purpose of this application is to occupy the PowerPC in the case that there is no other software application in the design. It simply keeps the PowerPC running in an endless loop.
ppc405_0. Click “OK”.
Default: ppc405_0_bootloop and select “Mark to Initialize BRAMs”. The icon will now have a small red cross signifying that it will not run on the PowerPC.
DIPTest.c in a folder called “DIPTest” within the project folder.#include "xparameters.h"
#include "xbasic_types.h"
#include "xgpio.h"
#include "xstatus.h"
XGpio GpioInput;
int main (void) {
Xuint32 status;
Xuint32 DataRead;
Xuint32 OldData;
// Initialize the GPIO driver so that it's ready to use,
status = XGpio_Initialize(&GpioInput,
XPAR_DIPSWS_4BIT_DEVICE_ID);
if (status != XST_SUCCESS)
return XST_FAILURE;
// Set the direction for all signals to be inputs
XGpio_SetDataDirection(&GpioInput, 1, 0xFFFFFFFF);
// Initialize the old data register
OldData = 0xFF;
while(1){
// Read the state of the DIP switches
DataRead = XGpio_DiscreteRead(&GpioInput, 1);
// Send the data to the UART if the settings change
if(DataRead != OldData){
xil_printf("DIP Switch settings: 0x%X\r\n", DataRead);
OldData = DataRead;
}
}
return 0;
}DIPTest.c file that we just created and click “OK”.
The simple C program that we added to this project simply reads the DIP switch settings and sends a message with that data to the UART.
Add the GPIO for the LEDs
Now we will manually add the second GPIO for the LEDs.
opb_gpio 3.01b and select “Add IP”.
opb_gpio_0. Click on the instance and rename it to LEDs_4Bit. XPS automatically modifies the system.mss and system.mhs files to include the new IP details.LEDs_4Bit tree and selecting “opb” for the “SOPB” bus connection.
LEDs_4Bit instance. We can modify the instance parameters using this dialog box. type 4 for the “GPIO Data Bus Width” and click OK.
LEDs_4Bit tree.GPIO_IO net should display “No Connection”. Click on “No Connection” and type fpga_0_LEDs_4Bit_GPIO_IO to give the net a name.
system.mhs file to include the new external port.LEDs_4Bit size drop-down menu and select 64K. Then click “Generate Addresses”. XPS automatically reconfigures the memory map and gives the LEDs GPIO a base address and a high address. It also automatically modifies the system.mhs file to update the IP address details.

We have now created an instance of the GPIO peripheral in our design.
Modify the Constraints (.UCF) File
The remaining details to include in the hardware description are the external pin connections of the LEDs. This is specified in the system.ucf file which is up to the user to modify according to the external hardware configuration (ie. How the FPGA pins are wired up on the XUPV2P board). Follow these steps to modify the constraints file:
#### Module LEDs_4Bit constraints
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<0> LOC=AC4;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<0> IOSTANDARD = LVTTL;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<0> SLEW = SLOW;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<0> DRIVE = 12;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<1> LOC=AC3;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<1> IOSTANDARD = LVTTL;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<1> SLEW = SLOW;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<1> DRIVE = 12;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<2> LOC=AA6;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<2> IOSTANDARD = LVTTL;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<2> SLEW = SLOW;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<2> DRIVE = 12;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<3> LOC=AA5;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<3> IOSTANDARD = LVTTL;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<3> SLEW = SLOW;
Net fpga_0_LEDs_4Bit_GPIO_IO_pin<3> DRIVE = 12;
Modify the Software Application
Now the hardware definitions are complete and we must modify the software application to test the hardware.
LEDTest.c in the “LEDTest” folder.#include "xparameters.h"
#include "xbasic_types.h"
#include "xgpio.h"
#include "xstatus.h"
XGpio GpioOutput;
XGpio GpioInput;
int main (void) {
Xuint32 status;
Xuint32 DataRead;
Xuint32 OldData;
// Clear the screen
xil_printf("%c[2J",27);
// Initialize the GPIO driver so that it's ready to use,
status = XGpio_Initialize(&GpioOutput,
XPAR_LEDS_4BIT_DEVICE_ID);
if (status != XST_SUCCESS)
return XST_FAILURE;
// Set the direction for all signals to be outputs
XGpio_SetDataDirection(&GpioOutput, 1, 0x0);
// Initialize the GPIO driver so that it's ready to use,
status = XGpio_Initialize(&GpioInput,
XPAR_DIPSWS_4BIT_DEVICE_ID);
if (status != XST_SUCCESS)
return XST_FAILURE;
// Set the direction for all signals to be inputs
XGpio_SetDataDirection(&GpioInput, 1, 0xFFFFFFFF);
OldData = 0xFFFFFFFF;
while(1){
// Read the state of the DIP switches
DataRead = XGpio_DiscreteRead(&GpioInput, 1);
// Send the data to the UART if the settings change
if(DataRead != OldData){
xil_printf("DIP Switch settings: 0x%X\r\n", DataRead);
// Set the GPIO outputs to the DIP switch values
XGpio_DiscreteWrite(&GpioOutput, 1, DataRead);
// Record the DIP switch settings
OldData = DataRead;
}
}
}LEDTest.c file into the “Project: LEDTest” source files by right-clicking on “Source” and selecting “Add Existing Files”.Download and Test the Project
The simple C program that we added to this project simply reads the DIP switch settings and sends a message with that data to the UART. It also writes the same values to the LEDs. When the application is running and Hyperterminal is open, the DIP switch settings should be seen on the LEDs and on the Hyperterminal screen. Change the DIP switches to see the message change.
After a few changes in the DIP switches, the Hyperterminal output should look similar to the screen shot below:
The project folder for this tutorial can be downloaded in a compressed ZIP file EDKTutorial.zip . Right-click on the link and select “Save Link As”.
In the next tutorial, Create a Peripheral Using the Peripheral Wizard, we develop our own custom peripheral for reading the DIP switches and writing to the LEDs.