VHDL: Xilinx ISE

Now that we've discussed VHDL itself, it's time to learn the development environment. If you don't already have it installed, you will want to install the Xilinx ISE WebPACK. The ISE Foundation is a professional tool that will cost you an arm and a leg. The ISE WebPACK is a free version of the software that does most of what you need (unless you have large, complex designs or are working with the newest and best Xilinx FPGAs). If you know ahead of time which series of FPGAs you plan to use, you can save time and disk space by only installing the files for that FPGA series. Once you've got that installed, fire it up.

Creating a new project
If you already started a project, just select File > Open Project and find your project file. Otherwise, we'll start a new one from scratch.

Go to File > New Project to start the New Project Wizard. Give your project a name. Something not too long that will help you find the files later. Then give the program a location to put the project; ISE will create a subfolder in that directory with the name of your project. And finally, your top-level source type is HDL (Hardware Description Language).

The next dialog box asks a whole lot of questions. But worry not; we'll keep it fairly simple. Choose your device family; for our project that will be the Spartan-3A (on the pull-down menu you'll find "Spartan3A and Spartan3AN"). The device is unknown for our project. We plan to design the VHDL first, then find out how large of an FPGA we need to hold our design. So just go ahead and pick the smallest Spartan-3A: XC3S50A. If need be we'll adjust the project later to use a larger FPGA. If you know the package, go ahead and select that. However, once again, we'll probably figure that out later, so I just left the default. Skimming down past several options you can leave alone (unless you know you're using something other than the defaults), make sure your simulator is set to "ISE Simulator (VHDL/Verilog) and your preferred language is VHDL. Then go ahead and hit next.

If you want to create a brand-new file right up front, go ahead. However, I will explain creating new files a bit later, so you can just skip this step and add the files later. Click next. If you have existing source files from somewhere else that you want to include, this is the place for you. Chances are you're starting from scratch, so you can just click next. Then you get a summary box to make sure you got everything right. If so, click Finish.

Creating a new VHDL file
So you've got a project. Now you need some files in your project. Go to Project > New Source. Select "VHDL Module", give your file a name (don't bother with the .vhd; ISE will add that for you) and a parent directory. Click next. Here's where you start to love ISE, as it will do some work for you. If you read the previous pages of the tutorial, you read about entities, architectures, and ports. ISE now gives you a GUI to define these; give your entity and architecture a name. If you know what your ports will be, go ahead and define them: a name, in/out/inout, line/bus, indices if you're using a bus. If you don't know what your ports will be (or want to change them later), you can just edit the code manually with no problems. Click next. You get a screen to verify all the details you just set up and if you're all set, click finish. The new file will be added to the Sources box to the top left and will open up in the main window. The file will have all sorts of predefined code for you; the library/use statements, some standard comments to describe the file, and the framework for your code.



If you already had a file created and you just wanted to open it, take a look at the Sources box to the top left. Make sure the pull-down menu above it is set for "Synthesis/Implementation" and the "Sources" tab is selected below it. Double-click the file you want. Depending on your code, ISE will sort your files into hierarchies at times, so you may need to click the little plus signs to find the desired file. Take a look at the image to the left to see what the Sources box looks like.

Now let's explain what some of that box means. Find the line that has the device and package codes (in the picture it says "xc3s50a-4tq144"). Above that you really don't need to worry about too much. Below that is a list of all your files. You can see that every file has the format "entity_name - architecture_name (file_name.vhd)". If you named things well, you can usually only worry about the entity name to find what you need.

The first file ("DAC_box") has a funny little icon next to it: three rectangles, the topmost of which is green. That icon means that the DAC_box file is the "top module". You can synthesize the top module, but the others cannot be synthesized. Since you'll want to synthesize different components at different times, just remember that before synthesis you have to reset your top module. This is done by right clicking on the file you want set as top and selecting Set as Top Module.

You can see that ISE has established a hierarchy of files. The DAC_box has a DAC_controller and a DAC_emulator. The DAC_controller has a DAC_hold19, a DAC_shiftreg, and a DAC_delay, and the DAC_emulator part list is collapsed. In front of each of these files lower in the hierarchy there is a u number. The u number is a shorthand designation of which part is which (discussed in VHDL:_The_real_code). Your files can appear in multiple places, as well. For example, the DAC_subemulator (no u number because it is an independent part not used in the DAC_box) has a DAC_hold19 and a DAC_shifter.

Synthesis


Those of you familiar with computer programming may think of this step as "compiling", but since you're not generating an executable file it's not really the same thing. Synthesis is the step that takes your VHDL code and generates from it a schematic for your circuit.

Once you've written your code and are ready to see how the schematic looks, go up to the Sources box and set it as the top module. And make sure that the file you wish to synthesize is selected. Then go down to the Processes box and double click on "Synthesize - XST". If you do not see that option, then you forgot to set your file as the top module. The User Constraints section allows you to tie certain I/O lines to specific pins on the package. You can see that in the image Synthesis - XST has a little yellow triangle with an exclamation point next to it. That means that the design has synthesized with no errors but has warnings. Double click on "View Synthesis Report" to see any errors and warnings. Some warnings can safely be ignored, others must be take care of. An error will generate a red icon. If ISE is uncertain if the latest version of the file has been synthesized or not, it will place an orange icon with a question mark. And of course a green icon with a check mark means that the synthesis completed with no errors and no warnings. Double clicking Synthesize - XST runs the synthesis, and you can right click and select rerun if you want to be sure the file is up-to-date.



Once you've synthesized your design, double click on "View RTL Schematic". RTL stands for Register Transfer Level. This gives you what is effectively a block diagram of your circuit, with all the gates and parts in place and wired together. As discussed in previous sections, a thick wire is a bus. By extension, a part drawn with thick lines has bus I/O but performs the same function for all lines of the bus. Inputs are shown on the left as arrows pointing to the right with lines and buses coming off the points of the arrows. Outputs are shown on the right as arrows pointing to the right with lines and buses entering the flat ends of the arrows. Branches of the wires are shown as dots at the intersection points; intersections without dots are separate wires that happen to cross without connecting to each other. To enter a block, simply double click on it. To exit a block and go back to the next higher schematic, you can right click and select "Pop to the Calling Schematic."

You can also double click "View Technology Schematic." This is similar to the RTL schematic, however there is no blocking of components together functionally, nor will multiple lines be combined into buses. It can be a rather large, intimidating, and confusing view so it is not often used, as RTL gives the same information in a much more comprehensible fashion.

Simulation
Now that you've written your code and seen the RTL schematic (then fixed your code and seen the new RTL schematic and repeated that whole process a few times) it's time to see if it actually works. To do that you need to run a simulation. Unfortunately, it's not that easy; you first need to define a test bench waveform (.tbw) file.



Go to Project > New Source and select "Test Bench Waveform." Give the file a name and choose a parent directory, then click next. The next dialog box will ask you which source file to associate with the text bench waveform file. Select the file you wish to text and click next. Verify the details you just selected and click finish. This will bring up the dialog box shown to the right. Chances are you won't need to change (or even worry about) most of that window. However in the bottom right corner you can see "Initial Length of Test Bench". The default value for that tends to be too small for a design of any size; I generally set it to 10,000. You can try to be clever and change it from 10,000 ns to 10$$\mu$$s, but it won't work; changing the time unit adjusts other values across the dialog box. So just type in "10000" (or whatever other number you feel is best).

If you have an existing .tbw file that you want to use, go to the Sources box, change the pull-down menu to "Behavioral Simulation", and double click on the file you want.



So now you have your test bench waveform open. Your screen will look something along the lines of the one shown to the left. In the main section of the screen you see the waveforms for the inputs and outputs. You can change which waveforms are shown. To delete a waveform, click on the name and press the delete key. To add a waveform (including internal signals if you want to monitor those), go to the Processes box in the bottom left and double click on the name of the signal you wish to add to the waveform.

A line will appear as a waveform like the ones in the image. A bus will appear as a thick line with a value on the line and a narrow point at a transition. You can set whether the value is to be displayed in hex, binary, or decimal. You can also click the plus sign next to the name to expand the bus into a set of lines.

To set the values, simply click on the waveforms wherever you want the value to be toggled. If you wish to use one of the 7 non-binary logic levels (shown here) or to set a pattern for ISE to fill in for you, right click on the waveform where you wish to start the pattern or non-binary logic level and select "Set Value." Beware of having too many transitions, as it is possible to crash the program that way.



Once you have defined your input waveforms (don't bother trying to set your output waveforms; those get defined by the simulator), you are now ready to simulate. Go to the Processes box and double click "Simulate Behavioral Model" (under "Xilinx ISE Simulator"). ISE will think for a bit then open a new window like the one shown to the right. This shows the input and output signal waveforms. You can see the internal bus count (highlighted) expanded to show both the bus notation mentioned above (values in hex) and the individual line waveforms. You'll have to study these waveforms closely to debug many of your designs. Timing hazards may appear here (a signal fires a clock cycle too early or too late and ruins the synchronization of the entire device, etc.). If you look over this design and decide you are happy with the output, then you have successfully designed and done basic testing in VHDL.

Going further with ISE
ISE will do more than is described here. This is just the basic functionality. As I mentioned briefly, you can use the constraints editor to tie a certain signal to a certain pin in order to coordinate with your PCB designer. ISE will generate your programming files (mapping and routing your design onto the selected FPGA) and open up iMPACT, the program which will program your FPGA (or perhaps the PROM you attach to your FPGA).