Xilinx Tools Tutorial
qweqwe
Introduction
The Xilinx Integrated Software Environment (ISE) is a powerful and
complex set of tools. The purpose of this guide is to help new users get
started using ISE to compile their designs. This guide provides a very
high-level overview of how the tools work, and takes the reader through
the process of compiling. The ultimate reference to ISE is of course the
official documentation, which is installed on every PC in the lab, and
is available from the
Xilinx
website. Because the documentation is so voluminous, this guide will
attempt to provide some help with finding the right sections of the
documentation to read. Don't miss the required reading section at the
end of this guide which points out some sections of the documentation
that every 6.111 student should read before beginning a complex labkit
project.
From HDL to FPGA
The process of converting hardware design language (HDL) files into a
configuration bitstream which can be used to program the FPGA, is done
several steps.
First, the HDL files are synthesized. Synthesis is the process of
converting behavioral HDL descriptions into a network of logic gates.
The synthesis engine takes as input the HDL design files and a library
of primitives. Primitives are not necessarily just simple logic gates
like AND and OR gates and D-registers, but can also include more
complicated things such as shift registers and arithmetic units.
Primitives also include specialized circuits such as DLLs that cannot be
inferred by behavioral HDL code and must be explicitly instantiated.
The libraries guide in the Xilinx documentation provides an complete
description of every primitive available in the Xilinx library. (Note
that, while there are occasions when it is helpful or even necessary to
explicitly instantiate primitives, it is much better design practice to
write behavioral code whenever possible.)
In 6.111, we will be using the Xilinx supplied synthesis engine known as XST. XST takes as input a verilog (
.v
) file and generates a
.ngc
file. A synthesis report file (
.srp
)
is also generated, which describes the logic inferred for each part of
the HDL file, and often includes helpful warning messages.
The
.ngc
file is then converted to an
.ngd
file. (This step mostly seems to be necessary to accommodate different
design entry methods, such as third-part synthesis tools or direct
schematic entry. Whatever the design entry method, the result is an
.ngd
file.)
The
.ngd
file is essentially a netlist of primitive
gates, which could be implemented on any one of a number of types of
FPGA devices Xilinx manufacturers. The next step is to map the
primitives onto the types of resources (logic cells, i/o cells, etc.)
available in the specific FPGA being targeted. The output of the Xilinx
map tool is an
.ncd
file.
The design is then placed and routed, meaning that the resources described in the
.ncd
file are then assigned specific locations on the FPGA, and the
connections between the resources are mapped into the FPGAs interconnect
network. The delays associated with interconnect on a large FPGA can be
quite significant, so the place and route process has a large impact on
the speed of the design. The place and route engine attempts to honor
timing constraints that have been added to the design, but if the
constraints are too tight, the engine will give up and generate an
implementation that is functional, but not capable of operating as fast
as desired. Be careful not to assume that just because a design was
successfully placed and routed, that it will operate at the desired
clock rate.
The output of the place and route engine is an updated
.ncd
file, which contains all the information necessary to implement the
design on the chosen FPGA. All that remains is to translate the
.ncd
file into a configuration bitstream in the format recognized by the
FPGA programming tools. Then the programmer is used to download the
design into the FPGA, or write the appropriate files to a compact flash
card, which is then used to configure the FPGA.
Constraints
By itself, a Verilog model seldom captures all of the important
attributes of a complete design. Details such as i/o pin mappings and
timing constraints can't be expressed in Verilog, but are nonetheless
important considerations when implementing the model on real hardware.
The Xilinx tools allow these constraints to be defined in several
places, the two most notable being a separate "universal constraints
file" (
.ucf
) and special comments within the Verilog model.
A
.ucf
file is simply a list of constraints, such as
net "ram0_data<35>" loc="ab25"
which indicates that bit 35 of the signal
ram0_data
(which
should be a port in the top-level Verilog module) should be assigned to
pin AB25 on the FPGA. Sometimes it is useful to combine several related
constraints on one line, using "|" characters to separate constraints.
net "ram0_data<35>" loc="ab25" | fast | iostandard=lvdci_33 | drive=12;
The above example again assigns bit 35 of the signal
ram0_data
to pin AB25, and also specifies that the i/o driver should be
configured for fast slew rate, 3.3V LVTTL level signaling (with a
built-in series termination resistor), and a drive strength of 12mA. See
the Xilinx documentation for more details, but don't worry: all of the
pin constraints have been written for you (more on this later).
Constraints can also be specified within special comments in the Verilog code. For example,
reg [7:0] state;
// synthesis attribute init of state is "03";
The Xilinx synthesis engine will identify the phrase "synthesis
attribute" within any comments, and will add the constraint following
this phrase to the list of constraints loaded from a
.ucf
file. In the above example, the initial state of the
state
signal after the FPGA finishes configuring itself will be set to
8'h03
.
In general, it is bad form to specify the initial state of signals
using constraints, rather than implementing a reset signal. In some
advanced designs, however, such initializations are sometimes necessary.
The tools recognize a huge variety of constraints, and an entire
section of the online manual is dedicated to explaining them.
Fortunately, understanding a few simple constraints is sufficient for
most designs.
ISE and the 6.111 Labkit
The FPGA used in the labkit has 684 i/o pins, and most of them are
actually being used. To simplify the process of adding pin constraints
to a new design, two template files have been developed
The file
labkit.v
is a template top-level Verilog module.
This module defines names for all of the signals going in or out of the
FPGA. Additionally, it provides default assignments for all FPGA
outputs, so that unused circuits on the labkit are disabled. A template
constraints file,
labkit.ucf
ties the signals in
labkit.v
to the appropriate physical FPGA pins.
A Tutorial
Download the following source files:
Create a New Project
- Select "New Project" from the "File" menu
- Enter a project name and choose a project location. Be sure the top-level module type is set to HDL (hardware design language).
- On the next form, enter the target device information. The FPGA
on the labkits is a Virtex 2 family XC2V6000, speed grade 4, in a BF957
package.
- The next form allows you to create a new source file. If you
have already written the Verilog code for your project, click "Next" to
advance to the next form, which allows you to add existing source files.
You can also add existing files to your project later, after the
project has been created.
- After creating or adding any source files, click "Next" until
you reach the project summary form, and then click "Finish" to create
the project.
Add Sources and Constraints
- If you did not add all of your Verilog source files when creating
the project, add them now by choosing "Add Source..." from the "Project"
menu.
Modify the Top-Level Template
- To instantiate the counter module, add the following code to
labkit.v
, just before the endmodule
statement.
counter counter1 (.clock(clock_27mhz), .led(led));
- The stock
labkit.v
file assigns a default value to the LED outputs. In order to drive the LEDs with the counter
module, we need to delete the following line, which can be found near the end of labkit.v
.
assign led = 8'hFF; // Turn off all LEDs
Compile the Design
- The
labkit.ucf
file includes constraints for all of the FPGA outputs defined in labkit.v
.
Most designs, however, will not use all of these signals, in which case
the synthesis engine will optimize the unused signals out of the
design. It is therefore necessary to tell the place-and-route tool not
to generate an error if it encounters a pin constraint for a (now)
nonexistent signal. To do this, right-click on the "Implement Design"
item in the process pane, and select "Properties...". Check the box to
"allow unmatched LOC constraints".
- Make sure the top-level
labkit
module is selected in the sources window.
- Double click "Generate Programming File" in the tasks window.
This will cause the "Synthesize", "Implement Design" and "Generate
Programming File" tasks to be run in order. A green check mark will
appear beside each task when it is successfully completed. It will take
approximately 5 minutes for everything to complete. (The tools seem to
hang for a few minutes while generating the pad report, but this
normal.)
Move the Design to a Compact Flash Card
- In the process pane, double-click on "Generate PROM, ACE or JTAG
file". (You may have to expand the "Generate Programming File" line to
see this item.)
- The iMPACT programming tool will launch, and a wizard will ask
you several questions about what you want to do. You want to generate a
SystemACE file.
- When asked to choose between the CF and MPM versions of SystemACE, choose CF (Compact Flash). The operating mode is unimportant.
- It is not necessary to specify the size of the CF card.
- Choose a name and a location for the SystemACE file collection you are about to generate.
- SystemACE allows up to eight designs to be stored on a single
CF card. A switch on the labkit selects which design will be loaded into
the FPGA. Check the boxes for as many designs as you want to include on
the CF card.
- iMPACT will ask you to add design files for each configuration.
You can potentially add more than one design file for each of the eight
configurations (if there were more than one FPGA on the board, for
example), but for the labkits, only add one design per configuration.
- Ignore the warnings about changing the configuration clock.
- Once all of the configurations have been specified, choose "Finish" and generate the
.ace
files. This takes a minute or two.
- Right click anywhere in the upper pane of the iMPACT window
(with the system diagram) and select "Copy to CompactFlash...". Select
the collection you just generated and copy it to the CF card.
- Insert the CF card in the labkit. Make sure the configuration
source is set to "JTAG/CF", and select the configuration selector switch
to the appropriate number. Power on the labkit, and your configuration
should load.