Up untill now, you have been using Aldec Active-VHDL to test and simulate your VHDL projects. Foundation Express is a tool included with Xilinx Foundation v1.4 to allow the synthesis and download of VHDL designs onto an FPGA or CPLD. Foundation Express is a version of Synopsys's "FPGA Express" (you may see it called this in many places) that has been included with v1.4, and future versions of Xilinx Foundation will have Express fully integrated within the project manager.
This tutorial will outline the steps necessary to synthesize, download, and test the 4 bit adder from VHDL code.
Please send corrections to tsaimelv@pilot.msu.edu.
Brief Introduction
The primary "unit" that the Xilinx tools work with is the netlist. Xilinx Foundation can import and export various forms of netlists, including XNF (Xilinx Netlist Format), EDIF, EDN, structural VHDL, etc. However, Foundation itself does not create the final synthesized bitstream, it merely creates the netlists. When you click "Implement" from within Foundation, it invokes the Design Manager. Foundation simply "points" Design Manager to the location of your netlists. These netlists were created (usually) from the schematic editor, in EDIF format.
The function of Foundation Express is to create netlists directly from VHDL, specifically XNF netlists.. Once you create a netlist from your VHDL code, it can be directly opened within Design Manager, bypassing Xilinx Foundation. You can also tell Design Manager which UCF file you would like to use, so that you can specify pin numbers (as in the previous tutorials).
However, you do not necessarily have to bypass Xilinx Foundation. A netlist created within Express can be imported and opened from within the Schematic Editor. From here it can be used as a macro component, whose underlying function is the netlist. Unfortunately, there are a number of extra steps involved when using such macros, most of which are non-obvious. I will likely create yet another short tutorial explaining this process, but if you need to know how to do this sooner, contact me directly.
To begin, start Foundation Express, and create a new project:
We will call this project "adder4." Make sure you create the project within an appropriate directory, such as your M:\ drive, or a subdirectory within it.
Immediately after this project is created, it will ask you to "identify sources," that is, tell Express which source files you plan to work with. Since we don't have any source files yet, click "Cancel."
To obtain our VHDL source file for the 4 bit adder, we use the following code, straight from the book:
entity FullAdder is
port (X, Y, Cin: in
bit;
-- Inputs
Cout, Sum: out
bit); --
Outputs
end FullAdder;
architecture Equations of FullAdder is
begin
-- Concurrent Assignments
Sum <= X xor Y xor Cin
after 10 ns;
Cout <= (X and Y) or (X and Cin) or (Y and
Cin) after 10 ns;
end Equations;
entity Adder4 is
port (A, B: in bit_vector(3 downto
0); Ci: in bit; -- Inputs
S: out bit_vector(3 downto
0); Co: out bit); -- Outputs
end Adder4;
architecture Structure of Adder4 is
component FullAdder
port (X, Y, Cin: in
bit;
-- Inputs
Cout, Sum: out
bit); --
Outputs
end component;
signal C: bit_vector(3 downto
1);
begin --instantiate four copies of the
FullAdder
FA0: FullAdder port map (A(0), B(0), Ci, C(1),
S(0));
FA1: FullAdder port map (A(1), B(1), C(1), C(2),
S(1));
FA2: FullAdder port map (A(2), B(2), C(2), C(3),
S(2));
FA3: FullAdder port map (A(3), B(3), C(3), Co,
S(3));
end Structure;
Save this text in a file called "adder4.vhd" and place it in the following directory:
[your chosen directory]/adder4/workdirs/Work.
Now you can tell Express to use this adder4.vhd file you just created. Go back to Express and right-click on "WORK", which brings up a menu. Click on "Identify sources in WORK".
Point to adder4.vhd from within your /adder4/workdirs/Work and click "Open."
Immediately after you've added adder4.vhd, it will analyze the VHDL code for errors. You will get a warning when this happens:
"Warning: Signal assignment delays are not supported for synthesis."
The next steps will explain why we get this error, and how to fix it.
Right-click on adder4.vhd and go to "Edit File." This brings up an editor window that will allow us to modify our code.
You'll notice that the error referrs to signal assignment delays, specifically the following:
architecture Equations of FullAdder is
begin
-- Concurrent Assignments
Sum <= X xor Y xor Cin
after 10 ns;
Cout <= (X and Y) or (X and Cin) or
(Y and Cin) after 10 ns;
end Equations;
A simulation program such as Active VHDL can deal with these delays. However, when the circuit is compiled and downloaded onto a chip, what piece of hardware allows you to delay for 10 ns? What if we wanted to delay 132.4 ns instead of 10 ns? The point is that there is no way to synthesize a delay from within hardware. To get delays, you must rely on the system clock, or you rely for the real-world delays of the circuit (of which we have little control over). So, to fix the above warnings, we must simply remove these "after 10 ns" statements. Since our design is a static, combinatorial circuit, we do not need to include such delay statements. If your design absolutely requires delays or "wait for __ ns" statements, then it will have to be fundamentally changed before it can be synthesized within Express.
There is one other thing that must be added to our code. Recall that in the XS40 tutorial, we added "RESET" and "CHIPSEL" signals so that the microcontroller and the SRAM of the XS40 board would be disabled. We must do the same thing from within VHDL. Simply add two new ports to our Adder4 entity: RESET and CHIPSEL. We must also assign these ports a value of '1' (Vcc), just as before.
After the above changes, we now have our final VHDL code, with changes in bold:
entity FullAdder is
port (X, Y, Cin: in
bit;
-- Inputs
Cout, Sum: out
bit); --
Outputs
end FullAdder;
architecture Equations of FullAdder is
begin
-- Concurrent Assignments
Sum <= X xor Y xor
Cin;
Cout <= (X and Y) or (X and Cin) or (Y and
Cin);
end Equations;
entity Adder4 is
port (A, B: in bit_vector(3 downto
0); Ci: in bit; -- Inputs
RESET, CHIPSEL: out
bit;
S: out
bit_vector(3 downto 0); Co: out bit); -- Outputs
end
Adder4;
architecture Structure of Adder4 is
component FullAdder
port (X, Y, Cin: in
bit;
-- Inputs
Cout, Sum: out
bit); --
Outputs
end component;
signal C: bit_vector(3 downto
1);
begin --instantiate four copies of the
FullAdder
RESET <= '1';
CHIPSEL <=
'1';
FA0: FullAdder port map (A(0), B(0), Ci, C(1), S(0));
FA1: FullAdder port map (A(1), B(1), C(1), C(2), S(1));
FA2: FullAdder port map (A(2), B(2), C(2), C(3), S(2));
FA3: FullAdder port map (A(3), B(3), C(3), Co,
S(3));
end Structure;
Make these changes within in the editor, then save it.
We must now tell Express to update itself, so right-click on adder4.vhd and click "Update File."
The green checkmark on the adder4.vhd means that our code is now syntactically correct. To create the netlist from this VHDL code, we must perform three steps. First, we must create the implementation. Click on the "Adder4" block and then click on the "create implementation" button (in the image above, Adder4 is highlighted, and the Create Implementation button is being pointed to by the mouse). We clicked on the Adder4 block because it's our top level component, just like in Aldec.
Once you click on Create Implementation, the above window will pop up. Make sure you change your Device to "4010XLPC84", which is the FPGA used in our XS40 boards. There are other parameters that you can play with (such as optimizing the design for speed or area, etc.), but for now leave them as shown above. Click OK.
Click on the item that says "Adder4 (Xilinx-XC4000:4010XLPC84xl-09)" as shown above, then click the "Optimize" button.
The synthesized netlist of our VHDL has been created, so now we can export it to Design Manager. Click on "Adder4-Optimized" then click "Export Netlist."
Find a directory to export the netlist to. Personally, I prefer to create a subdirectory called "exported" from within my design directory, such as adder4/exported. Once you've located a suitible directory, click "Save." The XNF netlist of your VHDL will now be placed within this directory (adder4.xnf).
Before we can open this netlist from within Design Manager, we must first create a UCF file to specify the XS40 pin numbers we wish to use. This UCF file is very similar to the one used in the previous tutorial, but within a few changes.
UCF File:
NET Ci LOC = P81;
NET A<0> LOC = P28;
NET A<1> LOC = P60;
NET A<2> LOC = P58;
NET A<3> LOC = P50;
NET B<0> LOC = P56;
NET B<1> LOC = P51;
NET B<2> LOC = P57;
NET B<3> LOC = P59;
NET S<0> LOC = P41;
NET S<1> LOC = P40;
NET S<2> LOC = P39;
NET S<3> LOC = P38;
NET Co LOC =
P35;
NET RESET LOC = P36;
NET CHIPSEL LOC = P65;
The pin numbers haven't changed since the last tutorial, but notice how you specify individual signals of a bit_vector from within the UCF file. You use the "<" and ">" brackets instead of conventional parenthesis ")(".
Save this UCF file from within your /exported directory, as adder4.ucf.
Now we can invoke the Design Manager and compile our design. Click on "New Project."
Click on 'Browse' under Input Design, which brings up the above window. Find your 'exported' directory, and specify our netlist. Click "Open".
After your Input Design (netlist) has been specified, click OK. We now have a new project with our XNF netlist specified as our input. Now go to Design|Implement, then click on Options.
In the options window, click on all the same options as you did in the previous tutorial, i.e. remember to click on 'Produce Timing Simulation Data', etc. However, here is the place where we specify our UCF file. Click "Browse" next to "User Constraints" and look for your UCF file.
Also, remember to specify a timing data output in VHDL format. To do this, click on "Edit Template."
Under "Interface", click on "VHDL" as your simulation data format option. Click OK.
We are now ready to create the bitstream and timing simulation files. Click "Run" and wait for the design to finish.
After your design has completed (and there are no errors), we can check the
"Pad Report" to see if your UCF file was interpreted properly:
Pad Report:
Pinout by Component Name:
+------------------------------------------------------------+--------------+
|
Component
Name
| Pin Number |
+------------------------------------------------------------+--------------+
|
A<0>
| P28 |
|
A<1>
| P60 |
|
A<2>
| P58 |
|
A<3>
| P50 |
|
B<0>
| P56 |
|
B<1>
| P51 |
|
B<2>
| P57 |
|
B<3>
| P59 |
|
CHIPSEL
| P65 |
|
Ci
| P81 |
|
Co
| P35 |
|
RESET
| P36 |
|
S<0>
| P41 |
|
S<1>
| P40 |
|
S<2>
| P39 |
|
S<3>
| P38 |
+------------------------------------------------------------+--------------+
As you can see, each of our signals was assigned to the correct pin.
Simulating the Post-Synthesis Design
Notice how your adder4/exported directory now contains the important files:
adder4.bit (bitstream used to download to the XS40 board)
and
time_sim.vhd, time_sim.sdf
These files are the VHDL netlists of our compiled design. After the
design was compiled and synthesized onto our XL4010 FPGA, a structural VHDL
representation of this circuit was created. We can open this netlist from
within Active VHDL and simulate it. Time_sim.vhd is the netlist, and
time_sim.sdf specifies the real-world delays you would encounter when actually
running the design on the FPGA. This allows us to perform a
timing-accurate simulation of our final circuit, as opposed to a static
or unit-delay simulation.
To use this simulation data, create a new project from within Active VHDL. I recommend that you place the project it in a new subdirectory under /adder4, but it's up to you.
After you've created the project and the "New Design Wizzard" comes up, click on "Add existing resource files" then click on "Next."
Browse to find time_sim.vhd and time_sim.sdf, then add both of these files into your design.
Time_sim.vhd contains some odd code that allows for different simulation features. For example, it contains two different configurations, as well as the standard "Adder4" entity. We don't need to deal with the configurations, so when the "Top-Level Selection" window pops up, select "Entity/Architecture" then click OK.
From here you can simulate your 4 bit adder just as before. There will be many weird internal signals that show when you're adding signals to your waveform, but you can ignore them and just focus on your primary signals: A, B, S, Ci, and Co. You also may want to look at the actual VHDL code of time_sim.vhd to see if you can understand what it's actually doing.
If anyone needs more help with simulating this from within Aldec, please contact me. Otherwise, the simulation is quite straightforward.
Testing your Design
After your simulation from within Aldec is working, you can look in your adder4/exported directory and find adder4.bit. This bitstream can be downloaded in the exact same fashion as outlined in the previous tutorial. All of the wiring to the XS40 board should be the same as well, since we used identical pin numbers from within the UCF file.