Xilinx Foundation 3.1
Xilinx Tutorial Using
This Student Edition of Xilinx Foundation has built-in limitations not found in the 'commercial' edition. FPGAs are limited to the XC4008 family, equivalent to 8,000 logic gates or 15,000 logic + RAM gates. Xilinx XC3000 and XC5000 families are not supported in this version.
Foundation v1.5
Lab Exercise #1
Introductory Tutorial
This lab exercise contains a tutorial which shows you how to create, using schematic-based entry, a 3-input combinatorial circuit. Specifically, the tutorial implements the following function:
That is, the end result of this tutorial is to implement this function onto an FPGA chip. One pin on the FPGA will be declared as an output (D), and three pins will be declared as inputs (A, B, C). Once the circuit is synthesized using the following tutorial procedures, you can test the circuit on the protoboard to see if it properly implements the function. It is recommended that you completely finish the tutorial procedure before you start the assignment (described below). This tutorial may seem long, but once you become familiar with the program, it will go quickly.
Your Assignment
Once you have followed the tutorial, you must then extend the tutorial's concepts to implement the function mentioned in your Lab2 handout.
Introductory Tutorial
Start the program by going to the 'Xilinx Foundation Project Manager' icon in the Start menu. There are many other icons in the menu that you can click on, including an extensive array of online documentation. It is recommended that you read the documentation included with Xilinx Foundation in addition to this tutorial.
Once started, you will see the main design window. We want to create a new project for this tutorial, so click on 'New Project':
The 'New Project' window will show up. Type in the name you want to call the project, as well as the specified directory. You cannot create a project in the default directory that first comes up, so specify C:TEMP or point it to somewhere in your M: drive. The files created by Xilinx Foundation can sometimes be large, so make sure you have a few megabytes free in your M: drive if you create the project there. The 'Name:' of the project will actually become the name of the subdirectory containing your project. For example, the files contained in the above project will be put into E:TEMPintro.
Next you must specify the 'Type' of project. Previous versions of Xilinx Foundation exclusively used the 'XACT step M1' project type. If you are using the Student Version (shown above in screenshot) select 'Foundation series v1.5' project type. For the version in the lab the only choice is 'Foundation 2.1i' which is the professional version of the software. By selecting either the 1.5 or 2.1i design flow, the 'Foundation' design environment will be more integrated and less confusing to use than past versions. Make sure to also keep 'Schematic' as the Flow so we can select the correct FPGA to target.
Finally you must specify the 'Family' and 'Part'. When creating designs with Xilinx Foundation, the program must know what type of chip you are dealing with. In ENG 241, we will usually only deal with one chip, the XC4005XL (the FPGA contained in the XS40 board in our labs). Depending on which chip you select, it can make drastic differences in how you enter schematic-based designs, so make sure you select the correct part # and family. The 'Speed' box specifies how fast our chip is capable of running, but for this class it will have little or no bearing on your projects.
Once you have created your project, there will be many files created within the project directory you specified. The most important ones show up in the left pane of the window. The 'INTRO.UCF' file is the Universal Constraint File for your project. Editing this file allows you to change a number of different preferences and options for your project. Consult the online help or the Xilinx Student Edition book for more information on the UCF file. We will make use of this file later. The other files ('SIMPRIMS', 'XC4000EX', etc.) can be ignored for now.
Since this tutorial shows how to enter a circuit using schematic capture (that is, you draw schematics and the program will recognize what you draw), we must first create a blank schematic sheet. Do this by clicking on the Gate picture within the 'Design Entry' portion of the design flow window.
Once the blank schematic sheet has been created, we can now start adding elements of our circuit. Do this by clicking on the Symbols Toolbox button.
Remember that this introductory tutorial implements the following function:
Also, 'AB' implies 'A AND B', and 'A+B' implies 'A OR B'. So, to construct the 'AB' portion of this function, we want to add a 2-input 'AND' gate to our circuit. Scroll down the symbol toolbox and find AND2. This is a 2-input AND gate. Click on its name once, then move the mouse pointer into a blank area of the schematic. Click once more and the gate will be placed into the schematic sheet. Take a while to get a feel for how to add, move, select, and delete schematic symbols as they're placed onto the sheet. It can be tricky.
Now we want to add a 2-input OR gate to our circuit. Just as before, find the OR2 entry and add it.
And finally we shall add an inverter. This will implement the 'NOT C' portion of our function. In order for this circuit to function, we obviously must add wires to interconnect the components. However, we will wait until the end to do this to make things easier.
Remember that the ultimate goal of this schematic is to have it be synthesized down to an FPGA. That is, the circuit that we draw will exactly be implemented inside the FPGA chip. In order for the program to properly recognize how we want this to be done, we must add 'input buffers' and 'output buffers.' These buffers tell Xilinx Foundation where we want physical inputs and outputs to be oriented on the FPGA.
Scroll down and find IBUF just as any other component. We will have three inputs and one output, so we must add three IBUFs.
For our output we must add an OBUF.
After we have added the IBUF's and OBUF's that define where we want inputs and outputs, we must then add 'pin identifiers.' These allow us to name the IBUF and OBUF pins and declare them as true inputs or outputs to the synthesizer. Once we add the input and output terminal identifiers, we can then use these as 'pin names' during simulation of the circuit.
To add an Input Terminal, click on the button in the upper left of the 'SC Symbols' sub window (the little window with all the AND2, OR2, etc. components). The 'I/O Terminal' window will then appear. We'll call our first pin A, so type this into the Terminal Name input box. Click OK and then place the symbol just as any other component.
Notice how the I/O terminal 'A' is a different color than the other symbols. Place it near the first IBUF. Again, we'll connect wires later.
Proceed to add two more Input Terminals, 'B' and 'C.' Place them under the first terminal 'A.'
Since we have an output pin, our final I/O terminal must be an output. Name it 'D.'
After all the components have been added, this is what it should look like. Notice the difference in appearance between the Input and Output terminals.
All components have been placed, so now we need to connect them with wires. Do this by clicking on the 'Draw Wires' button.
To draw wires between components, left-click once, move the mouse pointer, then left click again to end the wire. Just as in placing components, adding and editing wires can be tricky so get experiment with wire placement. If a wire has not been properly placed, it will automatically erase itself after you try to do something else. It is difficult (but not impossible) to screw up placement of wires. It gets especially tricky when dealing with busses, but we won't be adding busses at this point.
Here is the schematic with a few more wires to go...
Here is the completed 3-input function schematic. Wasn't that easy!?
Now you should save the schematic. When you click 'save,' the schematic file will be automatically added to the project directory. Note that it is possible to have multiple schematics within a single project.
We must now create the netlist for our schematic. When Foundation creates the netlist, it creates a file that contains a low-level description of our file, consisting of primitive components connected together using text-based statements. It is very similar to a pspice .cir file.
After it creates the netlist, it gives you some warnings, see below:
The warning says 'terminals for top level schematic.' This warning was generated for a specific reason... Foundation and most other EDA software packages now focus on modular and hierarchical design. The schematic that we just drew, for example, could be put into it's own 'component' symbol and then used within another schematic in a nice-and-neat fashion. These are called macro functions. However, we want this schematic to be implemented directly within the FPGA and will not be used as a module in another design, so it gave us this warning. For now we can ignore it, it will have no effect on our circuit.
After the netlist was created, we perform an integrity test. This tests the netlist to see if it obeys certain design rules that it must follow.
The test passed, our design doesn't break any design rules.
After the netlist was created and tested, it must now be 'exported' for use in the main design. The process of netlist exporting tells the FPGA synthesizer what files and what organization the final FPGA will have.
We want to select the Edif 200 format (*.EDN) for exporting. The other formats are irrelevant for this laboratory exercise.
You don't need to change the filename or extension (intro.alb). Xilinx handles this, simply click 'open' after you've selected Edif 200 format.
After all that, you can now close the schematic editor and go back to the project manager. We now want to see if our schematic actually works. This is done by simulation of the circuit, click on the Waveform and Gate picture within the 'Simulation' portion of the design flow window.
This is the simulation environment provided by Foundation. Right now we'll only be performing a static timing analysis. That is, we're assuming that the gates and wires that we created from within the schematic are infinitely fast. This simulator will not account for real-world gate delays, capacitance, etc. that could alter real-world simulation results. Only after the design has been compiled and synthesized can the simulator account for such delays. In any case, our circuit is so simple that we can effectively ignore any delays in the circuit. Our FPGA boards can run this circuit with speeds in excess of 75MHz, far faster than anything we'll need.
We must first specify what parts of our circuit we want the simulator to monitor. Click on 'Add Signals.'
In this window we must select the signals we want the simulator to deal with. These signals are contained within the 'Signals Selection' pane. We can ignore the 'Chip Selection' and 'Scan Hierarchy' panes right now.
In the Signals Selection pane, you see the four I/O terminals that we added within our schematic, A, B, C, and D. Click on 'A' and then click 'Add'.
A red checkmark indicates that it has been added into the simulator. Proceed to add the other three terminals.
All four terminals have been added, inputs A, B, and C, as well as output D. Click on 'close' to go back to the simulator window.
Note that the four signals are now placed in the simulator window.
Since A, B, and C are inputs, we must add some sort of driving signals so that we can test to see if our output 'D' is actually working properly (hence the reason we perform simulation). We will first add a driver to signal 'A'. Click on signal 'A' and it will be highlighted with a blue shadow.
Click on 'Add Stimulators' after A has been highlighted.
The 'Stimulator Selection' window will then come up. This window is a bit confusing, and I recommend that you eventually read the Xilinx online documentation on how to use all the features of the Stimulator Selection window.
The row of 'lights' after the Bc: each correspond to a different bit in a 16-bit binary counter (Bc stands for binary counter). In this fashion, we can make any input be driven by a bit in this counter. Click on the least significant bit of Bc: to make A become part of this 16 bit counter. If you are confused about this, don't worry, you'll see what this does in a moment.
After this button is clicked, notice how signal A gets a 'B0'placed after it in the simulator window.
Proceed to do the same for B and C, but use the next two digits of the counter. For example, where the mouse pointer in the above window points is the button you should click for signal C. B gets a 'B1' after it and C gets a 'B2.'
We to do a functional (static) simulation, so make sure 'Functional' is highlighted.
We can now finally perform the simulation. Select a Step size of 200 nanoseconds from the drop-down box and Click the 'Step' button to run the simulation.
The following results should show up. If the waveforms are all scrunched together or you can't see anything but a short dark line behind A, B, and C, then your window scale is miscalibrated. See the next image:
To 'compress' the waveform so that more fits on the screen, click on the button that looks like an upside-down rake (where the mouse pointer is). To widen the waveform view, click on the other button (to the right of '500ps/div'). Widening the screen may be necessary in order to view any of the simulation, it depends on the default value the simulator opens with.
After you get the waveform to a scale you desire, you can now see what is going on. Notice how signal 'A' cycles twice for every one time B does, and B cycles twice every one time C does. This is because the stimulator was part of a binary counter, and C was the MSB and A was the LSB of this counter.
Since this is a combinational circuit, we want to test every possible input combination, and using bits of a counter is the easiest way. We can now produce a truth table based on the simulation results:
B | C | D | |
0 | 0 | 0 | 1 |
1 | 0 | 0 | 1 |
0 | 1 | 0 | 1 |
1 | 1 | 0 | 1 |
0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 |
1 | 1 | 1 | 1 |
You can verify that this truth table is exactly what should be produced by the circuit:
Specifying Pin Numbers within the UCF file -
Recall that the circuit we have implemented will be downloaded onto an FPGA chip. But, how does Foundation know which pins we want to use? FPGAs have multiple 'generic I/O' pins, so we can specify which pin # we want to correspond to output D, inputs A, B, C, etc. We tell Foundation which pins we want to use through the UCF file. Double click on 'INTRO.UCF' above and a text editor will come up.
Notice that the UCF file already contains a number of items. However, as it says on the fifth line, all the lines that start with the '#' or '//' symbols are commented out, which means that the compiler will ignore them. Scrolling down, notice that the UCF file is basically empty except for comments (which outline many of the things you can specify from within the UCF file).
To specify pin numbers, we simply need to edit the above UCF file. To begin, select all the text inside the UCF file and delete it. We don't need anything in it to begin. Once you have deleted all the text within the UCF file, add the following lines to it, and then save the UCF file:
NET A LOC = P7;
NET B LOC = P8;
NET C LOC = P9;
NET D LOC = P41;
Notice what these statements mean... We are telling the synthesizer to place input 'A' at pin 7, input 'B' at pin 8, etc. This is why we needed to add the Input and Output Terminals to our schematic. When you download the synthesized circuit to the FPGA, we simply need to supply test signals to pins 7, 8, and 9, and the output on pin 41 will give the result of our 3-input function. The XC4005XLPC84 fpga chip is 84 pins, and it has over 70 'generic I/O' pins, so this means that we can specify virtually any pins for these functions. However, this FPGA chip is mounted inside something called the 'XSTend' board, and we cannot directly access any of the pins. We are limited to using the XSTend board's resources, including LED's and switches. As you will see later, the pin numbers were chosen for a reason.
Now that we have verified that the circuit works and specified the pin numbers we want to use, we must now synthesize the circuit into a format that we can download to the FPGA board. To do this, click on picture within the 'Implement' portion of the design flow window.
This brings up the implementation window. From here you can specify various options, revision and version names, etc for use in synthesis. In subsequent lab exercises we will have to modify various options within the 'options' button, but for now the default options should be fine. Click on 'Run.' This will start the circuit synthesis process. Make sure that the 'Part:' says XC4005XL-09-PC84. If it says another part number, then it was not properly specified at the beginning, and you must restart the tutorial.
The Flow Engine is simply a script that invokes a bunch of command-line synthesis tools. In theory, you could compile and synthesize your entire design using an MSDOS prompt. Don't worry if you don't understand what is happening in the above steps, it's beyond the scope of ENG 241.
When everything is done, you will see a 'Completed Successfully' message box will appear. If you do not see this message box then something went wrong. You can view the log file to see exactly what went wrong, and attempt to correct the problem. The most common type of error is a misnamed pin or entry in the UCF file.
At this point you can go to Tools Implementation EPIC Design Viewer/Editor if you want. The EPIC Design Editor actually shows you what the inside of your chip now looks like, including the wires that have been routed, the CLBs you have used, etc. Be patient, it can take quite a while to load (at first I thought the program had crashed, but a couple minutes later it showed up!). EPIC actually allows you to physically route/unroute connections, manually add functions, etc., but this capability is far beyond what we'll be using in ENG 241. For right now it's just 'neat' to see what your design looks like. To zoom in/out of your design, right click and shift-right-click (you can pan around the design by holding down the right mouse button as well). Also, check and uncheck various items in the 'layer visibility' box to see what happens!
A Quick Introduction to the XS40 FPGA Board
Before you download your completed design to the XS40 board, here is some introductory information on the board itself. The XESS Corporation has many products based around FPGAs and CPLDs. Our ECE department has obtained a number of the XS40 and XS95 fpga/cpld development boards, and these are what students in ENG 241 will be using.
This tutorial applies mainly to the XS40 board, although most information also applies as well to the XS95 board. The XS40 is a small development board containing a Xilinx XC4005XL series FPGA chip. This chip is a low-to-midrange size FPGA in comparison to other FPGAs that Xilinx manufacturers. Nonetheless, it is unlikely that you will 'fill up' the entire FPGA with the designs in ENG 241. The XC4005XL contains 400 'Configurable Logic Blocks' (CLBs), which corresponds to around 7000 to 20000 'usable gates.' This means that when creating a real-world hardware design, the XC4005XL chip can implement a circuit that is equivalent to about 7000 to 20000 'two-input NAND gates' (as you recall from circuit theory, any digital circuit can be broken down into a series of NAND or NOR gates). In the real world, this 'usable gate' specification doesn't really say much, as it is difficult or even impossible to gauge how many 'gates' a design will actually use.
As a side note, Xilinx makes one of the industry's largest FPGAs, the XC40250XV. This chip contains 8464 CLBs (corresponding to ~250000 usable gates, which is probably large enough to implement an entire Pentium-II processor on it). A single XC40250XV chip can cost upwards of $2000-$3000.
The FPGA in the XS40 board is an 84 pin 'plastic leaded chip carrier' (PLCC) version. You'll notice that the chip is square, and is housed in a brown socket. Most of the 84 pins on the chip can be used for generic I/O, which means that each pin's function can become anything you want (via the UCF file). The XS40 board has more than just the FPGA, however. It also contains an 8031 microcontroller. The 8031 is a derivative of Intel's very old (and still very popular) 8051 series of microcontrollers. It operates at about 12 MHz (although its performance is approximately equal to a 68HC11 running at 1 MHz), and most of its 32 I/O pins are routed to the FPGA. This means that if you want to use the FPGA's generic I/O pins that also happen to be connected to the 8031, we must 'disable' the 8031 so that it will not interfere. Disabling the microcontroller will be explained later. Note that we will likely never use the 8031 in any ENG 241 projects, but if your final design projects can benefit from the microcontroller, please contact me. You can also feed this 12 MHz clock source into the FPGA. Since this clock is generated from a ceramic resonator, it is very accurate and can keep time to within 0.0001%.
Connected to the 8031, and also to the FPGA, is a 32k static RAM chip. This chip is used to store the code for the 8031. However, the FPGA can also access this SRAM directly, although this process is a bit complex. See me if you want/need to use the SRAM in any ENG 241 design project. Note that this RAM chip is volatile, which means that it will be erased when the power is removed.
Another peripheral contained on the XS40 board is a VGA connector! Using a very simple resistor network, a 'crude' D/A converter is set up, making it possible to output Red, Green, and Blue values to a VGA monitor in the proper synchronization (up to 64 colors on the screen). With this connector, it's possible to create a character generator, make a 'paintbrush' style drawing program, display a picture stored in the SRAM chip, etc. right from the XS40 board. Of course, the process of outputting VGA signals through the FPGA's I/O ports is not easy, but there are some application notes on the XESS website that describe the process. In addition to the VGA connector, there is also a 7-segment LED contained on the board which allows you to display a single digit number from within your program/hardware.
The other connection on the XS40 board is a parallel port connector. We use this connector to download bitstreams to the FPGA, as well as program the 32k SRAM chip with 8031 code (if desired). The program used to download bitstreams to the boards is called XSTOOLS, which is separate from Xilinx Foundation (the download process is described next).
Note that the bitstream that you download to the FPGA is also volatile, which means that the FPGA is erased every time the power is removed. The XS95 (CPLD) board, however, retains its bitstream indefinitely, but can only be erased/reprogrammed a limited number of times (up to around 10000 write/erase cycles). The XS40 board can be reprogrammed an unlimited number of times. If you need the FPGA board to retain its bitstream even when power is removed, note that there is a socket for a ROM on the XS40 board. You can download the bitstream to this ROM and make it 'permanent,' but we will not be doing this in ENG 241.
At the XESS website you can download schematics, manuals, tutorials, etc. for the XS40 board. The XS40 schematic layout is available here. Note that there are several schematics contained with that pdf file. We have 'version 1.4' of the XS40 board, so you should probably print the page out your reference.
The XSTend Board
Our XS40 boards are mounted inside something called 'XSTend' boards. These give extra capabilities to the XS40 board, including switches, more LEDs, 16 bit D/A and A/D conversion, a PS/2 keyboard connector, more SRAM, and a prototyping area. Note that because we use the XSTend boards, we no longer have direct access to any free I/O pins. We will be using the various onboard functions of the XSTend board for most/all projects in this class.
After a bitstream has been downloaded to the XS40 board, we need some way to test the design. We will be using the switches and LED's on the XSTend boards to input signals to the FPGA and see the result.
Downloading the bitstream to the XS40 Board
If you look inside your project directory, you will see a file called 'intro.bit'. This is the file that will be downloaded to the XS40 board. Copy this file to the root directory of your M: drive, i.e. M:. This will make things easier.
First, you must make sure that you're at a computer in EB3270 that has an XS40 & XSTend board connected to it. If not, you must move to a computer with an XS40 board. Just make sure that you still access your 'intro.bit' file. Before you download to the XS40 board, make sure that the parallel port connector is properly connected to the XS40 board. Also make sure that the power supply is plugged into the XS40 board. When it's plugged in, the 7 segment LED display on the main board should be very faintly lit. If it's not lit at all, then something may be wrong.
Open up an MSDOS command prompt, and change directories to C:XSTOOLSBIN. 'Xstools' is the program supplied by XESS corporation to download files to their boards. To download 'intro.bit' to the XS40 board, simply type in the following:
Xilinx Foundation 3.1
This will invoke the program XSLOAD and download the bitstream. 'xess' is actually an MSDOS batch file which automatically selects LPT2 as our parallel port address, but you don't need to worry about that. If 'xess.bat' is missing, you can execute XSLOAD directly with the following syntax:
XSLOAD -p 2 intro.bit
After you execute XSLOAD, the program should download the file into the XS40 board. Note that XSLOAD is rather 'dumb' program, and it will download to the board even if it's not connected! There is no feedback mechanism that shows that the bitstream was properly downloaded. However, during download, the 7 segment LED display should momentarily flash on and off, perhaps showing a number or character. If there seems to be zero activity on the LEDs during download, something may be wrong.
Note that unplugging the 9V power supply from the XS40 board will erase the bitstream in the FPGA. You must redownload the bitstream each time power is removed.
Testing the Circuit
Based on the chosen UCF pin assignments, the circuit is already wired up to test (because the XSTend board's various peripherals are hardwired to various pins on the FPGA, and the pins we chose routed the inputs to 3 DIP switches [the DIP switch has 8 little switches on a blue mounting], and the output to the first element of the LED bargraph).
To test the circuit, you can apply all 8 possible combinations to the DIP switch positions 1, 2, and 3. These switches are connected to the inputs A, B, and C, respectively. When the switch lever is in the upright position (that is, the lever is closest to the label that says 'ON' and 'WP'), this is a logic 0. When you flip the switch to the other direction (closest to the switch #), it applies a logic 1.
Now, how will you know whether your circuit is working? Well, if you did everything properly, you should notice that one of the elements of the LED bargraph should be lit up. If not, try other combinations of inputs until it lights up. The LED's on/off state should reflect the truth table for your circuit. *However*, the LED's state is actually inverted. This means that when the circuit's output is a logic '0', the LED will be lit up. When the circuit is outputting a logic '1', the LED will go dark. Make sure you pay attention to this or you will be confused!
Running through the various switch combinations of switches 1, 2, and 3 should allow you to view the output 'D' when all possible input combinations are listed. You should be able to exactly reproduce the expected truth table of the circuit, keeping in mind that the LED will show the inverted state of what the circuit is actually doing. The LED is inverted because of the way the XSTend board implemented the circuit (it is actually an LED and a resistor tied to Vcc, so outputting a logic '0' will ground the LED and cause current to flow). The inversion has nothing to do with the FPGA. As always, if you need help, contact me via email or try to find me in the labs.
Remember to properly clean up the bench area after you're finished, including various wires, papers, etc. Also, remember to unplug the XS40 power supply when it's not in use, and don't leave any files in C:TEMP that others can steal!