[[TracNav(802.11/TOC)]] = Using the 802.11 Reference Design: SDK = The first step in modifying the 802.11 Reference Design software is creating a workspace in the Xilinx SDK and importing the reference software projects. The steps below describe how to create an SDK workspace containing the full software design. == Creating the SDK Workspace == 1. Ensure your Xilinx tools match the version used to create the reference design (see the [wiki:../../Download download] page for the current versions) 1. Ensure your local copy of the WARP edk_user_repository is up to date and in the repository search path of XPS (see [wiki:edk_user_repository edk_user_repository] for details) 1. Download the 802.11 Reference Design archive and expand .zip archive * Be sure the expanded archive path has no spaces; {{{C:/work/w3_802.11/}}} works, {{{C:/Documents and Settings/user/w3_802.11/}}} does not * The text below uses {{{/}}} as a placeholder for the XPS Project inside the expanded archive's '''EDK_Projects''' folder 1. Launch Xilinx SDK and select {{{/SDK_Workspace}}} as the active workspace 1. Select Xilinx Tools -> Repositories. In Local Repositories click New, then select {{{/}}} and click OK. Be sure to select the root of the XPS project (the folder containing {{{system.mhs}}}, '''not''' the SDK_Workspace folder. 1. Import the SDK projects provided by the reference design 1. Select File -> Import 1. Expand General -> Existing Projects into Workspace, click Next 1. Click Browse and navigate to {{{/SDK_Workspace}}} 1. 8 projects will be listed: {{{ wlan_bsp_cpu_high wlan_bsp_cpu_low wlan_mac_high_ap wlan_mac_high_ibss wlan_mac_high_sta wlan_mac_low_dcf wlan_mac_low_nomac Mango_802.11_RefDes_vX.Y_hw_platform <- the version number in this project name will change between releases }}} 1. Ensure all 8 projects are checked and click Finish 1. In the SDK Project Explorer: 1. For each CPU High project listed below, right-click the project name, select Change Referenced BSP, in the new dialog select {{{wlan_bsp_cpu_high}}}, then click OK * {{{wlan_mac_high_ap}}} * {{{wlan_mac_high_ibss}}} * {{{wlan_mac_high_sta}}} 1. For each CPU Low project listed below, right-click the project name, select Change Referenced BSP, in the new dialog select {{{wlan_bsp_cpu_low}}}, then click OK * {{{wlan_mac_low_dcf}}} * {{{wlan_mac_low_nomac}}} 1. Right click on each software project and select Clean Project 1. The 5 software applications (AP, STA, IBSS, DCF and NoMAC) should now build to completion. Click once on each project in the SDK Project Explorer tab and check the console for the message {{{elfcheck passed}}} Once you've created the SDK workspace you can begin modifying the reference C code. By default the SDK will automatically compile a software project when any of its source files are modified and saved. Watch the SDK console tab for compiler warnings/errors. == Using the Modified Design == When the SDK has successfully compiled the software projects for CPU High and CPU Low, you can use the updated design in hardware. The output of the XPS hardware implementation flow is a bitstream named {{{system.bit}}}. This bitstream contains the full hardware design. In this design the initial values of the memory blocks used for instruction/data are all zero. The SDK's Program FPGA tool (under the Xilinx Tools menu) implements the process of updating the memory blocks in {{{system.bit}}} with the software binary (the .elf file) generated by the SDK compiler/linker. The output of this flow is a new bistream named {{{download.bit}}}, ready to download to the FPGA. The Program FPGA tool requires selection of one software binary per processor in the design. You must select a valid .elf file per CPU. If you select the default bootloop, the corresponding processor will be configured with a "do nothing forever" application, leading to a boot failure of the 802.11 design. The image below shows the .elf selections to use the IBSS application in CPU High and DCF MAC in CPU Low:[[BR]] [[Image(wiki:802.11/files:sdk_program_fpga_elf_selection.png)]] After selecting valid .elf files click Program. This will generate the file {{{download.bit}}} in {{{/Mango_802.11_RefDes_vXXX_hw_platform/}}}. If you have a JTAG cable attached to your PC the tool will also attempt configuring your FPGA with the updated design. If no JTAG cable or FPGA is found, the tool will report "Program FPGA Failed". The {{{download.bit}}} file is still updated in this case and can be used to configure the FPGA later (via iMPACT, ChipScope, SD cards, etc). If you want to generate a .bin file for use on SD cards, find the updated {{{download.bit}}} file as described above and follow the usual [wiki:howto/SD_Config#BinaryFormat SD card config] flow. == Updating C Source Code == The Reference Design SDK Workspace uses software projects with "virtual" source code folders. These virtual folders refer to actual folders containing the source code files. This structure allows multiple software projects to share common source code without duplicating files. As of release v1.7.7 all C source code is stored in the {{{wlan-mac-sw}}} folder at the root of the {{{SDK_Workspace}}} folder. The 7 software projects use virtual folders to refer to the application, framework, and common code in the {{{wlan-mac-sw}}} folder. Thus, if you modify a file shared by multiple projects (such as {{{wlan_mac_low.h}}}) all software projects referring to that file will be updated automatically. The {{{wlan-mac-sw}}} folder in the reference design archive is '''not''' an SVN working copy. This is intentional, in hopes of avoiding accidental updates from known-good code (from a ref design archive) to in-progress code (from svn). However the organization of the {{{wlan-mac-sw}}} folder mirrors that of the C code in the SVN repository at [browser:/ReferenceDesigns/w3_802.11/c /ReferenceDesigns/w3_802.11/c]. This facilitates replacing the C code with a copy exported from a specific revision from the SVN repository. Replacing the source folder is a convenient way to migrate between minor revisions of the design that share a common hardware project. == Updating SDK Hardware BMM File == The Reference Design SDK workspace relies on a hardware project exported from XPS. The reference design archive includes a pre-built hardware project in the SDK_Workspace folder. If you modify the hardware design in XPS you will need to re-export the hardware from XPS into the SDK workspace. This is the standard process for exporting an XPS design to the SDK. However the 802.11 Reference Design requires a manual edit of one hardware project file in the SDK. The XPS hardware project includes a Block Memory Map ({{{system_bd.bmm}}}) file that describes the physical BRAM instances which are used for processor-addressable memory in the hardware design. The CPU High 256kB ILMB block is implemented as two 128kB blocks. The {{{.bmm}}} file describes these 128kB blocks separately. These blocks must be merged in the {{{.bmm}}} file so the SDK linker can use the full 256kB space when creating the final {{{.elf}}} executable. '''This process is only required if you export a new hardware design from XPS into the SDK. We have already applied this change to the hardware project distributed in the reference design .zip archive.''' After exporting the hardware project to the SDK: 1. Find the {{{SDK_workspace/Mango_802.11_RefDes_vX.Y.Z_hw_platform/system_bd.bmm}}} file 1. Open this file in a text editor and find the section starting with {{{ADDRESS_SPACE mb_high_lmb_bram_0_combined}}}. This section will have a {{{BUS_BLOCK}}} sub-section like: {{{ ADDRESS_SPACE mb_high_lmb_bram_0_combined RAMB32 [0x00000000:0x0001FFFF] BUS_BLOCK mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_0 RAMB32 [31:31] [0:32767] INPUT = mb_high_lmb_bram_0_combined_0.mem PLACED = XnYn; mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_1 RAMB32 [30:30] [0:32767] INPUT = mb_high_lmb_bram_0_combined_1.mem PLACED = XnYn; mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_2 RAMB32 [29:29] [0:32767] INPUT = mb_high_lmb_bram_0_combined_2.mem PLACED = XnYn; .... mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_30 RAMB32 [1:1] [0:32767] INPUT = mb_high_lmb_bram_0_combined_30.mem PLACED = XnYn; mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_31 RAMB32 [0:0] [0:32767] INPUT = mb_high_lmb_bram_0_combined_31.mem PLACED = XnYn; END_BUS_BLOCK; END_ADDRESS_SPACE; }}} 3. Immediately below this section will be another {{{ADDRESS_SPACE}}} block for the upper 128kB of the LMB: {{{ ADDRESS_SPACE mb_high_lmb_bram_1_combined RAMB32 [0x00020000:0x0003FFFF] BUS_BLOCK mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_0 RAMB32 [31:31] [0:32767] INPUT = mb_high_lmb_bram_1_combined_0.mem PLACED = XnYn; mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_1 RAMB32 [30:30] [0:32767] INPUT = mb_high_lmb_bram_1_combined_1.mem PLACED = XnYn; mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_2 RAMB32 [29:29] [0:32767] INPUT = mb_high_lmb_bram_1_combined_2.mem PLACED = XnYn; .... mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_30 RAMB32 [1:1] [0:32767] INPUT = mb_high_lmb_bram_1_combined_30.mem PLACED = XnYn; mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_31 RAMB32 [0:0] [0:32767] INPUT = mb_high_lmb_bram_1_combined_31.mem PLACED = XnYn; END_BUS_BLOCK; END_ADDRESS_SPACE; }}} 4. Move the second {{{BUS_BLOCK}}} section into the first {{{ADDRESS_SPACE}}} block, then delete the second (now empty) {{{ADDRESS_SPACE}}} block. 5. Change the address range of the combined {{{ADDRESS_SPACE}}} block to {{{[0x00000000:0x0003FFFF]}}}, describing the full 256kB LMB memory area. 6. When finished the single {{{ADDRESS_SPACE mb_high_lmb_bram_0_combined}}} block should look like: {{{ ADDRESS_SPACE mb_high_lmb_bram_0_combined RAMB32 [0x00000000:0x0003FFFF] BUS_BLOCK mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_0 RAMB32 [31:31] [0:32767] INPUT = mb_high_lmb_bram_0_combined_0.mem PLACED = XnYn; mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_1 RAMB32 [30:30] [0:32767] INPUT = mb_high_lmb_bram_0_combined_1.mem PLACED = XnYn; .... mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_30 RAMB32 [1:1] [0:32767] INPUT = mb_high_lmb_bram_0_combined_30.mem PLACED = XnYn; mb_high_lmb_bram_0/mb_high_lmb_bram_0/ramb36e1_31 RAMB32 [0:0] [0:32767] INPUT = mb_high_lmb_bram_0_combined_31.mem PLACED = XnYn; END_BUS_BLOCK; BUS_BLOCK mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_0 RAMB32 [31:31] [0:32767] INPUT = mb_high_lmb_bram_1_combined_0.mem PLACED = XnYn; mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_1 RAMB32 [30:30] [0:32767] INPUT = mb_high_lmb_bram_1_combined_1.mem PLACED = XnYn; mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_2 RAMB32 [29:29] [0:32767] INPUT = mb_high_lmb_bram_1_combined_2.mem PLACED = XnYn; .... mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_30 RAMB32 [1:1] [0:32767] INPUT = mb_high_lmb_bram_1_combined_30.mem PLACED = XnYn; mb_high_lmb_bram_1/mb_high_lmb_bram_1/ramb36e1_31 RAMB32 [0:0] [0:32767] INPUT = mb_high_lmb_bram_1_combined_31.mem PLACED = XnYn; END_BUS_BLOCK; END_ADDRESS_SPACE; }}}