Introduction to the Xilinx Platform Studio (XPS)

(compatible with WARP v2)

In this exercise, users will be introduced to the Xilinx Platform Studio (XPS). This tool is used by designers to build complete systems out of separate peripheral cores known as "pcores." In this exercise, user's will extend a provided template project by adding a custom pcore that implements a pseudorandom number generator (PRNG) directly in the FPGA. This core is then connected to the template project's User I/O core so it can drive random values out to LEDs and hexadecimal displays.


  • You have a WARP v2 board
  • ESD protection for the WARP board (wrist strap, etc)
  • USB cable and a DB9 serial cable for UART
  • Complete installation of ISE System Edition 13.4
  • Checked out a local copy of the WARP Repository
  • Set up a terminal on your computer using PuTTY or an alternative.
  • Familiarity with the Xilinx SDK. Make sure you have completed the Introduction to the SDK (w2) exercise.


In this exercise, we provide users with a custom peripheral core: the prng_useriosrc. This core is a pseudorandom number generator with ports that are meant to be connected to external pins on the FPGA. The above figure describes is a simplified diagram of the final after adding the custom pcore. Inside the custom core there is a Linear Feedback Shift Register (LFSR) that produces a sequence of pseudorandom values. These values are then latched by a counter circuit to slow them down and make their changes visible to the naked eye when observing a board. The output of this latch is sliced up and connected to output ports on the core. All pcores have two distinct ways of getting information into and out of the peripheral:

  • Ports: Shown in yellow in the above figure, ports allow direct connectivity between peripherals. They can serve as inputs or outputs of the design.
  • Registers: Shown in red in the above figure, registers allow peripherals to be controlled by software running in a PowerPC core. Registers allow the core to hang off a bus such as the Processor Local Bus (PLB) and allow custom C-code to read or write memory addresses to control the core.

The prng_useriosrc pcore has the following inputs and outputs:


  • User I/O Pushbutton Port: This port is connected directly to the User I/O "up" pushbutton port. When the user presses the button on the board, the latch inside the prng_useriosrc core will stop updating the outputs. This will effectively "pause" the core and allow the user to read the current set of outputs from the LEDs and other display elements.
  • Capture Period Register: This register attaches to the bus and allows C-code executing inside the PowerPC to control how often the latch on the LFSR triggers. In effect, this is a way for C-code to control how fast the output updates occur. Note: even though we have listed this as an input to the core, this register can also be read by the C-code in order to check and see what it had been set to.


  • Left/Right Hex Display Ports: These are unused in this WARP v2 variant of the Introduction to XPS exercise. They are tied to ground in XPS.
  • Red/Green LED Ports: The banks of red and green LEDs each contain 4 elements. These 4-bit wide random numbers drive the external pins that are connected to LEDs on the board.
  • Captured Output Register: This register attaches to the bus and allows C-code executing inside the PowerPC to read the current latched output of the LFSR.

You will also notice in the diagram the green "FPGA Pins" ports. These are top-level ports that are routed out to physical pins on the FPGA. These pins are connected to other components on the WARP board. For the purpose of this exercise, we have provided this pcore as an example of a hardware peripheral you may want to integrate into your design. The Exporting pcores from System Generator exercise covers how this pcore was created.


  1. Download either the WARP v2 Template Project.
  2. Extract the archive into a folder on your hard drive. Note: this folder must not contain any spaces in the path (this includes the the Windows desktop, as that lives in a folder known as "Documents and Settings").
  3. Navigate to this folder in Windows Explorer. Go into the SDK_workspace folder. These are the default SDK projects used in the Introduction to SDK exercise. We do not need them for this exercise. Delete the three folders in SDK_workspace (but do not delete SDK_workspace itself).
  4. Download the provided pcore. Unzip the archive and place the "prng_useriosrc_plbw_v1_02_a" folder inside the "pcores" folder in the extracted template project.
  5. Launch XPS from the Start menu. Click "Open project" and navigate to the system.xmp file from the template project. Click Open.
    • If this is the first time you have run XPS, you will receive a number of error messages saying that cores cannot be found. XPS must be told where to find the WARP SVN repository in order for it to find these files. In XPS, click Edit→Preferences. Then, under the "Application" category, click "Browse ..." under the "Global Peripheral Repository Search Path." Navigate to and select the "edk_user_repository" folder on your hard drive. If you do not have an "edk_user_repository" SVN working copy, please see our SVN documentation. After making this selection, close and reopen XPS. This step of adding the global repository path only needs to be done once per installation of the Xilinx tools.
  6. To connect the new pcore to the system, we will modify the Microprocessor Hardware Specification "system.mhs" You can find this file in the "Project" tab under "Project Files." Double-click this file to open it.

  1. Find the line of code near the top of the tile that starts with "PORT fpga_0_UserIO_LEDs_out_pin =" and replace it with the following:
PORT fpga_0_UserIO_LEDs_out_pin = GreenLEDs & RedLEDs, DIR = O, VEC = [0:7]

This chunk of core attaches the 8 User I/O LED pins to two new nets of 4 bits each. We'll hook these nets up to the new "prng_useriosrc" pcore.

  1. Find the following line and delete it:
PORT LEDs_out = fpga_0_UserIO_LEDs_out_pin

This is in the "warp_v4_userio" core. Basically, we are going to hijack control of the LEDs away from the User I/O core and attach it to our new "prng_useriosrc" core instead.

  1. Add the following two instances at the bottom of the MHS file:
BEGIN prng_useriosrc_plbw
 PARAMETER INSTANCE = prng_useriosrc_plbw_0
 PORT sysgen_clk = clk_80_0000MHzDCM0
 PORT leds_green = GreenLEDs
 PORT leds_red = RedLEDs
 PORT pause = UpPushbutton

BEGIN util_bus_split
 PARAMETER INSTANCE = util_bus_split_0
 PORT Sig = fpga_0_UserIO_PB_in_pin
 PORT Out1 = UpPushbutton
 PORT Out2 = net_gnd

The first creates and instance of the "prng_useriosrc" core, attaches it to the 80MHz bus, and attaches nets to its ports. The second instance simply slices off 1 bit from a bus of pushbuttons and attaches it to a net that is connected to the pause input port on the new core.

  1. Click File→Save. You will be asked if you want to reload the project; click "Reload." At this point, you may wonder how you are supposed to know the names of ports themselves. Unfortunately, ports that are floating (i.e. disconnected) do not show up in the system.mhs file. The best way to find a full list of all ports a pcore has is by looking at its entry in the "System Assembly View" tab. In the next step, we'll be looking at this view to verify that the prng_useriosrc pcore is correctly hooked up to the system.
  1. Open the System Assembly View tab and make sure you are looking at the "Bus Interfaces" subtab. To the left of prng_useriosrc_plbw_0, you see a yellow circle connecting the core to the "plb" bus (this is the 80MHz bus). Unconnected pcores show an empty, white circle.

  1. Next, click on the "Ports" subtab. Click the + next to the prng_useriosrc_plbw_0 core. The names shown next to the port are not the arbitrary net names we gave earlier (e.g. RedLEDs). Instead, this GUI shows what core each port is connected. It should look like this:

  1. Finally, click the "Addresses" subtab. In the bottom of the window, you will see the prng_useriosrc_plbw_0 core belongs to a class of "Unmapped Addresses." Each register needs to be mapped to a memory address in order for the C-code in the PowerPC to be able to read or write to it. Simply click the button in the upper right of the window to "Generate Addresses."

If successful, the "Unmapped Addresses" grouping will disappear and prng_useriosrc_plbw_0 will join the rest of the cores in the PowerPC's memory map.

  1. Now click the "Generate BitStream" on the far left of the window. This will take ~10 minutes on a fast computer.
  2. Once the project has finished generating the BitStream, click the "Export Design" button with the SDK logo on the far left of the window. Then click "Export & Launch SDK."
  3. The SDK will launch and will pull up a window for you to select your workspace. Navigate to the SDK_workspace folder you cleared out at the beginning of these instructions. Then click "OK."
  4. The SDK will now open and will have one project: the "_hw_platform" from the hardware design from XPS. You might recall from the Introduction to SDK exercise that two other software projects are needed to be able to run this design on the board: a Board Support Package (BSP) and a top-level software project. We will create these manually rather than import existing ones like in the Introduction to SDK exercise.
  5. Rather strangely, the Xilinx SDK does not automatically know about software drivers to custom peripherals in your XPS project. You have to explicitly tell the SDK where to find your hardware project. This is a step you have to do with every new SDK workspace. Click on the "Xilinx Tools" menu item and select "Repositories." Here, you want to ensure two things:
    • In Local Repositories, you want to point the SDK to the folder that contains the XPS project system.xmp file. Click on "New..." and navigate to and select this folder.
    • In Global Repositories, you want the SDK to point to the edk_user_repository folder on your hard drive. Unlike the local repositories, the SDK does remember this setting across workspaces. You'll only need to manually add the edk_user_repository the first time you run the SDK.
  6. Click the "New" button in the top left of the window.

  1. Click on "Xilinx Board Support Package" and click "Next."
  2. Click "Finish."
  3. A new window will pop-up that allows you configure the BSP with various optional software packages. For the purposes of this exercise, the default settings are fine. Just click OK. You will see the console at the bottom of the screen start printing messages as the SDK compiles the BSP. It will end up with "Finished building libraries" printed to the console.
  4. We're now ready build the actual software project that will control our custom core. Click the same "new" button above the "Project Explorer."
  5. Click "Xilinx C Project" and then click "Next."
  6. Click "Empty Application" under the "Select Project Template" dialog. This will rename the project to "empty_application_0." Change that name to "example_project." Click "Next."
  7. We have already created a BSP, so we do not want this dialog box to make another one for us. Click the radio button next to "Target an existing Board Support Package." Click "Finish"
  8. Download prng_example.c to somewhere on your harddrive.
  9. In the Project Explorer on the left side of the SDK, you will see the example_project_0 project. Click the + next to it and it will reveal a "src" folder. Drag the prng_example.c file from Windows explorer into this src folder. The project will immediately build. You can look through this C-code and see how it is different than the C-code that was provided in the template project and was used in the previous [warp:IntroToSDK Introduction to SDK] exercise. The differences are commented.
  10. Follow the same steps as in [warp:IntroToSDK Introduction to SDK] to generate a new linker script and download the design to the board.

Testing the Design

When you download the design and run the software, you should immediately see the LEDs displays start blinking randomly since they are being driven by the LFSR that is in this code.

When you press the "up" pushbotton of the top left of the board, you should see the User I/O LEDs and hexadecimal displays "pause" their current state.

As you press the button, your serial terminal on your computer will also print out the current state of the captured output register from the custom core.

WARP v2 Template Project - Example Application
                    Red LEDs  -------                 -------  Green LEDs
        PRNG Captured Value:  1 1 1 0 1 1 1 0 1 1 1 1 0 1 0 0

You can verify that the LEDs match the contents of the register.


The purpose of this exercise to show how data can get into and out of a custom core: through hardware ports and registers. While we used the User I/O core as the sources and sinks of the ports from the PRNG core, this process is fundamentally no different than I and Q samples being sent to and received from the radio bridge. The custom core we connected to the system in this exercise is a proxy for a custom physical layer-- the process is the same.

Additional Questions and Feedback

If you have any additional questions about this exercise or other feedback, please post to the WARP Forums.

Last modified 11 years ago Last modified on Dec 27, 2012, 9:09:52 AM

Attachments (8)

Download all attachments as: .zip