Writing Basic Software Applications Lab: Figure 1. Design Updated From Previous Lab
Writing Basic Software Applications Lab: Figure 1. Design Updated From Previous Lab
Objectives
After completing this lab, you will be able to:
Design Description
The purpose of this lab exercise is to Extend the processor system created in lab3 by adding a memory
controller (see Figure 1) and the writing a basic software application to access the LEDs on the Spartan-
3E starter kit.
Procedure
This lab is separated into steps that consist of general overview statements that provide information on
the detailed instructions that follow. Follow these detailed instructions to progress through the lab.
This lab comprises 4 primary steps: You will add an internal BRAM, invoke SDK and create application
project, analyze assembled object files and, finally, verify in hardware.
Note: If you are unable to complete the lab at this time, you can download the original lab files for this
module from the Xilinx University Program site at http://www.xilinx.com/university
1-1. Create a lab4 folder and copy the contents of the lab3 folder into the lab4
folder, or copy the content of the labsolution\ lab3 folder into the lab4
folder. Launch Xilinx Platform Studio (XPS) and open the project file.
1-1-1. Create a lab4 folder in the C:\ xup\ embedded\ labs directory and copy the contents from lab3 to
lab4, or copy the content of the labsolution\ lab3 folder into the lab4 folder.
1-1-2. Open XPS by selecting Start All Programs Xilinx ISE Design Suite 13.2 EDK
Xilinx Platform Studio.
1-1-3. Browse to the lab4 directory and open the project system.xmp.
1-2-1. From the IP catalog, add the following IP to the embedded hardware design, accepting the
default settings:
XPS BRAM Controller 1.00.b
Block RAM (BRAM) block 1.00.a
1-2-2. Connect the BRAM controller to the PLB and connect the BRAM to the BRAM controller (see
Figure 2).
1-2-3. Select a size of 8K for the XPS BRAM controller under Unmapped Addresses in Addresses tab,
and click Generate Addresses.
1-2-4. Generate hardware bitstream by clicking Hardware Generate Bitstream (this is to complete
the hardware flow in XPS before we start the software development flow in SDK.
2-1. Start SDK from XPS, generate software platform project with default
settings and default software project name.
Skip steps starting from 2-1-3 to 2-2 and remove lab3.c, if you were
continuing with lab3.
2-1-1. Start SDK by clicking Project Export Hardware Design to SDK ...
2-1-2. Click on Export & Launch SDK button with default settings and browse to
C:\xup\embedded\labs\lab3\SDK\SDK_Export.
Skip steps starting from 2-1-3 to 2-2 and remove lab3.c, if you were continuing with lab3.
2-1-4. Click Finish with default settings (with standalone operating system).
This will open the Software Platform Settings form showing the OS and libraries selections
2-1-5. Click OK to accept the default settings, as we want to create a standalone_bsp_0 software
platform project without requiring any additional libraries support.
The library generator will run in the background and will create xparameters.h file in the
C:\ xup\ embedded\ labs\ lab4\ standalone_bsp_0\ microblaze_0\ include\ directory.
2-1-6. Click on File in the Xilinx SDK window and select New Xilinx C Project.
2-1-7. Select Empty Application in the Select Project Template window, and enter TestApp as the
Project Name and click Next.
2-1-8. Select Target an existing Board Support Package and click Finish.
The TestApp project will be created in the Project Explorer window of SDK.
2-2. Import lab4.c file from the c:\ xup\ embedded\ source directory.
2-2-1. Select TestApp in the project view, right-click, and select Import.
2-2-2. Expand General category and double-click on File System, click next.
This will compile the source file and generate TestApp.elf in the
C:\ xup\ embedded\ labs\ lab4\ TestApp\ Debug folder
You will extend the functionality in lab4.c by adding code to display switch settings on the LEDs.
2-2-5. Open the GPIO API documentation by clicking on Documentation link of LEDs_8Bit peripheral
under the Peripheral Drivers section to opne the documentation in a default browser window.
2-2-6. View the various C and Header files associated with the GPIO by selecting File List at the top.
2-2-7. Click the header file xgpio.h and review the list of available function calls for the GPIO.
2-2-8. The following steps must be performed in the software application to enable writing to the GPIO:
1) Initialize the GPIO, 2) Set data direction, and 3) Write the data
2-2-9. Click on lab4.c in the Project Explorer view to open the file. This will populate the Outline tab.
Open the header file xparameters.h by double-clicking on xparameters.h in the Outline tab.
Note: The LEDS_8BIT matches the instance name assigned in the MHS file for this peripheral.
2-2-10. Modify your C code to echo the dip switch settings on the LEDS (Figure 9) and save the
application. The application will be compiled.
3-1. Generate linker script targeting .text section to ilmb and setting heap and
stack sizes to 400 each. Compile the application, and analyze the
assembled object files using the objdump utility.
3-1-4. Click somewhere in white space area in the lab4.c file, add a space and save it to recompile the
program.
3-1-5. Launch the Bash shell by selecting Xilinx Tools Launch shell.
3-1-6. Change the directory to TestApp/Debug using the cd command in the bash shell.
You can determine your directory path by using the pwd command.
3-1-7. Type mb-objdump -h TestApp.elf at the prompt in the shell window to list various sections of the
program, along with the starting address and size of each section
3-2. Change the location of the text section so that it resides in the XPS PLB
memory. Recompile the code, re-execute the objdump command, and
analyze the output.
3-2-3. Select the Code section to target in to XPS BRAM and click Generate.
3-2-4. Click somewhere in white space area in the lab4.c file, add a space and save it to recompile the
program.
4-1. Connect and power the board. Select TestApp.elf as the application to
intialize the BRAM with and program the FPGA from SDK.
4-1-4. Click on the drop-down button of the Software Configuration and select TestApp.elf application
to be targeted in BRAM.
4-1-6. Flip the DIP switches and verify that the LEDs will light according to the switch settings.
Verify that you see the results of the DIP switch and Push button settings in Hyper Terminal.
Figure 15. DIP Switch and Push Button settings displayed in Hyper Terminal
Note: Setting the DIP switches and push buttons will change the results displayed.
4-2. Change one of the xil_printf function calls to printf. Re-compile the code
and observe that the XPS BRAM space is not sufficient. Generate the linker
script to target the .text section to external memory (DDR2_SDRAM).
4-2-1. In the text editor, change the xil_printf function call to printf.
4-2-2. Compile the code and observe the output in the console window.
Observe in the console window that the .text section is too big and sections overlap.
4-2-4. Target .text section to DDR_SDRAM memory, click Generate, and click Yes to overwrite.
4-2-5. Click somewhere in white space area in the lab4.c file, add a space and save it to recompile the
program.
4-3. Initialize BRAM with bootloop application. Program the FPGA. Start the
xmd console window from SDK. Download the TestApp.elf application from
the xmd console window, and run the application.
4-3-1. In SDK, select Xilinx Tools Program FPGA, Click Program to initialized the BRAM with the
bootloop program, and program the FPGA.
Figure 17. Initialize BRAM with Bootloop and Program the FPGA
4-3-2. In SDK, select Xilinx Tools XMD Console to open an XMD console window.
Observe the Hyper Terminal window as the program executes. Play with dip switches and
observe the LEDs
4-3-7. In the XMD console window, type stop to stop the program execution. Close SDK and XPS.
Conclusion
Use SDK to define, develop, and integrate the software components of the embedded system. You can
define a device driver interface for each of the peripherals and the processor. SDK imports an MSS file
created in XPS and let you update the settings so you can represent the software side of the processor
system. You can then develop and compile peripheral-specific functional software and generate the
executable file from the compiled object codes and libraries. If needed, you can also use a linker script to
target various segments in various memories. When the application is too big to fit in the internal BRAM,
you can download the application in external memory using XMD, and then execute the program.
# ##############################################################################
# Created by Base System Builder Wizard for Xilinx EDK 13.2 Build EDK_O.61xd
# Tue Jul 12 06:55:41 2011
# Target Board: Xilinx Spartan-3E Starter Board Rev D
# Family: spartan3e
# Device: XC3S500e
# Package: FG320
# Speed Grade: -4
# Processor number: 1
# Processor 1: microblaze_0
# System clock frequency: 50.0
# Debug Interface: On-Chip HW Debug Module
# ##############################################################################
PARAMETER VERSION = 2.1.0
BEGIN microblaze
PARAMETER INSTANCE = microblaze_0
PARAMETER C_AREA_OPTIMIZED = 1
PARAMETER C_USE_BARREL = 1
PARAMETER C_DEBUG_ENABLED = 1
PARAMETER HW_VER = 8.20.a
BUS_INTERFACE DLMB = dlmb
BUS_INTERFACE ILMB = ilmb
BUS_INTERFACE DPLB = mb_plb
BEGIN plb_v46
PARAMETER INSTANCE = mb_plb
PARAMETER HW_VER = 1.05.a
PORT PLB_Clk = clk_50_0000MHz
PORT SYS_Rst = sys_bus_reset
END
BEGIN lmb_v10
PARAMETER INSTANCE = ilmb
PARAMETER HW_VER = 2.00.b
PORT LMB_Clk = clk_50_0000MHz
PORT SYS_Rst = sys_bus_reset
END
BEGIN lmb_v10
PARAMETER INSTANCE = dlmb
PARAMETER HW_VER = 2.00.b
PORT LMB_Clk = clk_50_0000MHz
PORT SYS_Rst = sys_bus_reset
END
BEGIN lmb_bram_if_cntlr
PARAMETER INSTANCE = dlmb_cntlr
PARAMETER HW_VER = 3.00.b
PARAMETER C_BASEADDR = 0x00000000
PARAMETER C_HIGHADDR = 0x00001fff
BUS_INTERFACE SLMB = dlmb
BUS_INTERFACE BRAM_PORT = dlmb_port
END
BEGIN lmb_bram_if_cntlr
PARAMETER INSTANCE = ilmb_cntlr
PARAMETER HW_VER = 3.00.b
PARAMETER C_BASEADDR = 0x00000000
PARAMETER C_HIGHADDR = 0x00001fff
BUS_INTERFACE SLMB = ilmb
BUS_INTERFACE BRAM_PORT = ilmb_port
END
BEGIN bram_block
PARAMETER INSTANCE = lmb_bram
PARAMETER HW_VER = 1.00.a
BUS_INTERFACE PORTA = ilmb_port
BUS_INTERFACE PORTB = dlmb_port
END
BEGIN xps_uartlite
PARAMETER INSTANCE = RS232_DCE
PARAMETER C_BAUDRATE = 115200
PARAMETER C_DATA_BITS = 8
PARAMETER C_USE_PARITY = 0
PARAMETER C_ODD_PARITY = 0
PARAMETER HW_VER = 1.02.a
BEGIN xps_gpio
PARAMETER INSTANCE = LEDs_8Bit
PARAMETER C_ALL_INPUTS = 0
PARAMETER C_GPIO_WIDTH = 8
PARAMETER C_INTERRUPT_PRESENT = 0
PARAMETER C_IS_DUAL = 0
PARAMETER HW_VER = 2.00.a
PARAMETER C_BASEADDR = 0x81440000
PARAMETER C_HIGHADDR = 0x8144ffff
BUS_INTERFACE SPLB = mb_plb
PORT GPIO_IO_O = fpga_0_LEDs_8Bit_GPIO_IO_O_pin
END
BEGIN mpmc
PARAMETER INSTANCE = DDR_SDRAM
PARAMETER C_NUM_PORTS = 1
PARAMETER C_SPECIAL_BOARD = S3E_STKIT
PARAMETER C_MEM_TYPE = DDR
PARAMETER C_MEM_PARTNO = MT46V32M16-6
PARAMETER C_MEM_DATA_WIDTH = 16
PARAMETER C_PIM0_BASETYPE = 2
PARAMETER HW_VER = 6.04.a
PARAMETER C_MPMC_BASEADDR = 0x8c000000
PARAMETER C_MPMC_HIGHADDR = 0x8fffffff
BUS_INTERFACE SPLB0 = mb_plb
PORT MPMC_Clk0 = clk_100_0000MHzDCM0
PORT MPMC_Clk90 = clk_100_0000MHz90DCM0
PORT MPMC_Rst = sys_periph_reset
PORT DDR_Clk = fpga_0_DDR_SDRAM_DDR_Clk_pin
PORT DDR_Clk_n = fpga_0_DDR_SDRAM_DDR_Clk_n_pin
PORT DDR_CE = fpga_0_DDR_SDRAM_DDR_CE_pin
PORT DDR_CS_n = fpga_0_DDR_SDRAM_DDR_CS_n_pin
PORT DDR_RAS_n = fpga_0_DDR_SDRAM_DDR_RAS_n_pin
PORT DDR_CAS_n = fpga_0_DDR_SDRAM_DDR_CAS_n_pin
PORT DDR_WE_n = fpga_0_DDR_SDRAM_DDR_WE_n_pin
PORT DDR_BankAddr = fpga_0_DDR_SDRAM_DDR_BankAddr_pin
PORT DDR_Addr = fpga_0_DDR_SDRAM_DDR_Addr_pin
PORT DDR_DQ = fpga_0_DDR_SDRAM_DDR_DQ_pin
PORT DDR_DM = fpga_0_DDR_SDRAM_DDR_DM_pin
PORT DDR_DQS = fpga_0_DDR_SDRAM_DDR_DQS_pin
PORT DDR_DQS_Div_O = fpga_0_DDR_SDRAM_ddr_dqs_div_io_pin
PORT DDR_DQS_Div_I = fpga_0_DDR_SDRAM_ddr_dqs_div_io_pin
END
BEGIN clock_generator
PARAMETER INSTANCE = clock_generator_0
PARAMETER C_CLKIN_FREQ = 50000000
PARAMETER C_CLKOUT0_FREQ = 100000000
PARAMETER C_CLKOUT0_PHASE = 90
PARAMETER C_CLKOUT0_GROUP = DCM0
PARAMETER C_CLKOUT0_BUF = TRUE
BEGIN mdm
PARAMETER INSTANCE = mdm_0
PARAMETER C_MB_DBG_PORTS = 1
PARAMETER C_USE_UART = 1
PARAMETER HW_VER = 2.00.b
PARAMETER C_BASEADDR = 0x84400000
PARAMETER C_HIGHADDR = 0x8440ffff
BUS_INTERFACE SPLB = mb_plb
BUS_INTERFACE MBDEBUG_0 = microblaze_0_mdm_bus
PORT Debug_SYS_Rst = Debug_SYS_Rst
END
BEGIN proc_sys_reset
PARAMETER INSTANCE = proc_sys_reset_0
PARAMETER C_EXT_RESET_HIGH = 1
PARAMETER HW_VER = 3.00.a
PORT Slowest_sync_clk = clk_50_0000MHz
PORT Ext_Reset_In = sys_rst_s
PORT MB_Debug_Sys_Rst = Debug_SYS_Rst
PORT Dcm_locked = Dcm_all_locked
PORT MB_Reset = mb_reset
PORT Bus_Struct_Reset = sys_bus_reset
PORT Peripheral_Reset = sys_periph_reset
END
BEGIN xps_gpio
PARAMETER INSTANCE = dip
PARAMETER HW_VER = 2.00.a
PARAMETER C_GPIO_WIDTH = 4
PARAMETER C_ALL_INPUTS = 1
PARAMETER C_BASEADDR = 0x81420000
PARAMETER C_HIGHADDR = 0x8142ffff
BUS_INTERFACE SPLB = mb_plb
PORT GPIO_IO_I = dip_GPIO_IO_I
END
BEGIN xps_gpio
PARAMETER INSTANCE = push
PARAMETER HW_VER = 2.00.a
PARAMETER C_GPIO_WIDTH = 4
PARAMETER C_ALL_INPUTS = 1
PARAMETER C_BASEADDR = 0x81400000
PARAMETER C_HIGHADDR = 0x8140ffff
BUS_INTERFACE SPLB = mb_plb
PORT GPIO_IO_I = push_GPIO_IO_I
END
BEGIN lcd_ip
PARAMETER INSTANCE = lcd_ip_0
PARAMETER HW_VER = 1.00.a
PARAMETER C_BASEADDR = 0xcf400000
PARAMETER C_HIGHADDR = 0xcf40ffff
BUS_INTERFACE SPLB = mb_plb
PORT lcd = lcd_ip_0_lcd
END
BEGIN bram_block
PARAMETER INSTANCE = bram_block_0
PARAMETER HW_VER = 1.00.a
BUS_INTERFACE PORTA = xps_bram_if_cntlr_0_PORTA
END
BEGIN xps_bram_if_cntlr
PARAMETER INSTANCE = xps_bram_if_cntlr_0
PARAMETER HW_VER = 1.00.b
PARAMETER C_SPLB_NATIVE_DWIDTH = 32
PARAMETER C_BASEADDR = 0x88208000
PARAMETER C_HIGHADDR = 0x88209fff
BUS_INTERFACE SPLB = mb_plb
BUS_INTERFACE PORTA = xps_bram_if_cntlr_0_PORTA
END