EDK and MD

From RCSWiki

Jump to: navigation, search

Contents

Creating a Partially Reconfigurable Design with Xilinx EDK (Modular Design with EDK)

Getting Started

The first step in this process is to create a "normal" system design using Xilinx's EDK Software. This will allow you to test a base system in non-reconfigurable form in order to verify its functionality. Once the EDK project has been built and tested, it is now time to "break-out" the portions that will be the reconfigurable modules.

Creating a Suitable Top-Level Design File

The Xilinx EDK software works by taking all of the IP cores that are included in your system and combining them into a top-level design (called system.vhd) at the time of synthesis. The modular design flow for partial reconfiguration requires, for the sake of simplicity and ease-of-use, that a top-level design should have a static side and a dynamic, or reconfigurable, side(s). The first step in partitioning the static and dynamic sides is to export the EDK project as an ISE sub-module. This process can be done by opening up the system design within XPS and selecting "Project Options" from under the "Options" menu. Next, select the "Hierarchy and Flow" tab and select the "This is a sub-module in my design option" and name the top-level instance (I use the name "static"). Next, click OK, and then select the "Export to ProjNav" option from under the "Tools" menu. This creates an ISE project in which the top-level design is called system_stub.vhd which instantiates all IOBs and BUFs and instantiates the "body" of the system (system.vhd) with the name given as the top-level instance.

Breaking Out The Modules

A new ISE project directory called "projnav" is created as the result of the export process. This ISE project is used for synthesizing the top-level skeleton of the design to use for floorplanning (area constraints, bus macro placement, etc.). Now, it is time to forget about synthesis for a while, and instead it's time to start coding structural HDL that will "pull" the reconfigurable modules out of the system.vhd file so that they can be instantiated individually in the top-level design so that they can be constrained in the modular design flow. The easiest way to do this is to remove the instantiations of the desired modules from the system.vhd (AKA static.vhd) file and to add them to the system_stub.vhd (AKA top.vhd) file. Next, the port list of the static.vhd file must be modified to allow for the reconfigurable modules to communicate with it (so inputs and outputs must be added). Also, this is a good time to add localized constant outputs (1's and 0's) from each of the reconfigurable modules and to the static module for bus macro control, etc.

Once all of the port editing and re-instantiations are complete, I hook all of the newly added ports from the static side to top-level signals with names that start with "s_*" and the same is done with the dynamic (reconfigurable) modules only with names that start with "d_*". The next and final step is to connect all the d_* signals to the s_* signals via bus macros. This is done by instantiating the desired width of bus macro (wider bus macros can be built by creating a wrapper that instantiates a variable number of bm's), and then connect its inputs, outputs, and tri-state input (both left and right side). At this time, it is also time to decide which side (left or right) is dynamic and which is static so as to hook up the bus macros properly.

Once the process of instantiating and attaching bus macros is done, one will be left with a top-level design file that contains only IOB and bus macro instantiations, static module(s), and dynamic module(s) - which abides to the rules of both the modular design process AND the partial reconfiguration flow process.

Partial Reconfiguation Tool Flow

From here on, the instructions closely follow the work of Gregory Mermoud (gregory.mermoud@epfl.ch) in his paper "A Module-Based Dynamic Partial Reconfiguration Tutorial", however I will paraphrase his work with some annotations that I feel are important. Before continuing I would create the following directory structure within the already existing project:

  • synth directory (used for module synthesis)
    • directory for each sub-module
  • imp directory (used for module implementation and assembly)
    • directory for each sub-module
    • directory for final top-level assembly
    • directory for PIMs (Physically Implemented Modules)

Initial Budgeting

The first step is to synthesize a "skeleton" of the top-level design by leaving all components as black-boxes. This is done by opening up the ISE project that was created during the export process and removing all of the underlying sources from the project. Next, synthesize the top-level file and copy the synthesis output (the top.ngc file) to imp/top_initial. Next, make sure that the bus macro file (.nmc file) is also in the imp/*/ directories. Bus macro files can be downloaded from the Xilinx Application Note 290 documentation. The next step is to generate an NGD file so that floorplanning can be done and initial area constraints for modules and locations of bus macro TBUFs can be pinned down. This is done by going to the imp/top_initial directory and NGDBuilding the top.ngc file

  • ngdbuild -modular initial <top-level module netlist, .ngc>
    • $> ngdbuild -modular initial top.ngc

This will create a top.ngd file which can be opened up in Floorplanner so that area constraints and bus macro locations can be created (these will be annotated in the top.ucf file). The rules for area constraints and bus macro locations abide by Xilinx's magical "Rule of 4" (documented in Mr. Mermoud's DPR tutorial and Xilinx's XAPP290) - which makes sure that design constraints always lines up with the CLB routing matrix of the FPGA. The .ucf file that is created must have the following information: area group annotations for each module AND bus macro instantiations for every bus macro (required names for modules and bus macros can be seen in the component list within Floorplanner).

NOTE --> .ucf syntax differs for different FPGA architectures, the following examples are for a Xilinx Virtex II-Pro 30 Chip on an ML310 evaluation board.

  • Area Group Annotations (example is done for a module named "static_0")
    • INST "static_0" AREA_GROUP "AG_static_0";
    • AREA_GROUP "AG_static_0" MODE=RECONFIG;
    • AREA_GROUP "AG_static_0" RANGE = SLICE_X0Y159:SLICE_X59Y0, TBUF_X0Y159:TBUF_X58Y0, RAMB16_X0Y0:RAMB16_X0Y19, RAMB16_X1Y1:RAMB16_X1Y18, RAMB16_X2Y0:RAMB16_X2Y19, RAMB16_X3Y1:RAMB16_X3Y18, RAMB16_X4Y1:RAMB16_X4Y18, MULT18X18_X0Y0:MULT18X18_X0Y19, MULT18X18_X1Y1:MULT18X18_X1Y18, MULT18X18_X2Y0:MULT18X18_X2Y19, MULT18X18_X3Y1:MULT18X18_X3Y18, MULT18X18_X4Y1:MULT18X18_X4Y18 ;
    • (Where "static" is the name of the component in the HDL, and "static_0" is the delimited component in the .ngd file)

NOTE --> There must only be a single RANGE annotation per area group in which all the area constraints are concatenated. Floorplanner does not do this for you, so the .ucf file must usually be modified by hand.

  • Bus Macro Instatiations (example is done with a "_" bus delimiter)
    • INST "be_macro_bus1" LOC = "TBUF_X56Y24" ;
    • (Where "be_macro" is the name of the instantiated macro in the HDL, and "_bus1" is the delimited bus number in the .ngd file)

NOTE --> Bus macro instantiations also follow the "Rule of 4" and must lie 4 units to the left of a module boundary so that they straddle the boundary evenly on both sides.

Once the .ucf file has been created, it is recommended to make a copy of it (*.ucf.bak) because the Xilinx Floorplanner usually adds invalid constraints to bus macro instantiations and area group ranges AND it often re-arranges the files into non-sensical orders (i.e. moving all comments to the top of the file, away from the lines that were intended to be commented). The .ucf backup is useful when making changes with Floorplanner and using the numbers that it generates and adding it to the hand-written .ucf file yourself, so that it only contains annotations that are wanted and/or needed.

Once the .ucf file has been completed it is time to add the constraints to the top-level skeleton by peforming the following command (again, make sure that the .ucf file and .nmc files are in the directory):

  • ngdbuild -modular initial <top-level module netlist, .ngc>
    • $> ngdbuild -modular initial top.ngc

Active Module Implementation

Now it is time to build each of the active modules that will be used in the top-level design. First, each module must be synthesized and its netlist (.ngc) file should be copied from the module's synth/ directory to module's subdirectory under the imp/ directory. Also, the netlists of any entities that this module uses must also be copied into this directory. Next, copy the top-level .ucf file into each of the imp/ directories. The .ucf file is used to make sure that when the module abides by the rules of the top-level constraints even though it is being built by itself as an individual module. The build process works as follows: (Note: Make sure the bus macro .nmc file is in the directory)

  • ngdbuild -modular module -active <module_name> -uc top.ucf <path to initial top-level netlist, .ngc>
    • Annotates the constraints to the design file for the module, produces .ngd file
    • $> ngdbuild -modular module -active dynamic -uc top.ucf ../top/top.ngc
  • map <design file, .ngd>
    • Maps the logic of the design to the fabric of the FPGA, produces .ncd file
    • $> map top.ngd
  • par -w <mapped design file, .ncd> <placed and routed design file, .ncd>
    • Places and routes the the design, produces a placed and routed .ncd file
    • $> par -w top.ncd top1.ncd
  • pimcreate -ncd <placed and routed design file, .ncd> <path to PIM directory>
    • Publishes a Physically Implemented Module (PIM) to the PIM directory for later assembly
    • $> pimcreate -ncd top1.ncd ../pims/

Assembly of the Modules

The entire design can be assembled together once all of the active modules have been implemented using the procedure described in the previous section. The first step is to copy the top-level netlist (top.ngc) and the top-level constraint file (top.ucf) from the imp/top-level_initial directory to the imp/top-level_final directory. The assembly process then works as follows: (Note: Again, make sure that the bus macro .nmc file is in the directory)

  • ngdbuild -modular assemble -pimpath <path to PIMs> -use_pim <PIM 1>...-use_pim <PIM N> <top-level design netlist, .ngc>
    • Assembles all of the PIMs into a single design file, produces .ngd file
    • $> ngdbuild -modular assemble -pimpath ../pims/ -use_pim static -use_pim dynamic top.ngc
  • map <design file, .ngd>
    • Maps the logic of the design to the fabric of the FPGA, produces .ncd file
    • $> map top.ngd
  • par -w <mapped design file, .ncd> <placed and routed design file, .ncd>
    • Places and routes the the design, produces a placed and routed .ncd file
    • $> par -w top.ncd top_routed.ncd

Bitstream Generation

Once final assembly of the modules is complete it is time for bitstream generation and partial reconfiguration tests, section will be completed soon.... Currently 2 Xilinx WebCases have been opened and both, after months of waiting, have become developmer issues (bugs seem to be in the tool, and not our source). Once we and Xilinx figure out the problem, further results and tips will be posted. Here is a snippet from Xilinx's reply:

    RTRJVM Project:
        It looks like it is just a bug in the software, and there is currently no
      workaround. The problem is now in the developers hands, and so it will hopefully be
      fixed in a future release or service pack. 
        Since I have filed a CR and the developers have the problem, I am going to go ahead
      and close this case. If we come across a workaround, I will let you know. 
      Best Regards,
         Xilinx WebCase Team

New News

Both the 6.3i and 7.1i tools (according to Xilinx) have serious "bugs" in the software that make partially reconfigurable designs impossible to create. Both of these tools have trouble following the rules set forth by modular design, as well as having trouble with some of the primitive components needed in a typical EDK design. We are currently working around these issues right now, and partially reconfigurable designs are being created and tested to see if our new "flow" works as needed.

Additionally, we have been working with Xilinx FAEs to get our system up and running using the Early Access PR Tools (6.3, 7.1, and 8.1), however there are still MAJOR problems in the toolflow. Updates will be posted as we make more progess on these issues.

Personal tools