Steps to Follow in ISE (FPGA LAB)
By: Umar Shahbaz Khan
1.
2.
3.
4.
Open ISE.
Go to File and select New Project
Give project name, destination and select HDL in top-level source type then click Next.
For SPARTAN 6: In the next window select All for product category, Spartan 6 in Family,
XC6SLX45 in Device, CSG484 in Package, -3 in Speed, XST (VHDL/Verilog) in synthesis
tool, ISE Simulator (VHDL/Verilog) in simulator and Verilog as preferred language. Select
Next, Next and Finish.
5. Now on the left hand side you have your selected FPGA model. Right click on it and
select add new source, in the new source wizard select Verilog module and give a name,
in the port name put in your inputs and outputs for 2x1 Mux this is 3 inputs a, b, sel and
2 outputs out and outbar. Note that you can also assign a bus as well. Press next and
Finish.
6. You can see that the wizard has created a basic module with all ports for you. You can
also do this manually by typing it yourself.
7. Now you can type the remaining section of your code:
assign out = sel ? a:b;
assign outbar = ~out;
8. Once done click on the Mux1 in the left hand panel and you will see a number of process
open in the bottom left plane. Double click on Synthesize-XST you will get a green check
if the code is correct. (Type a wrong syntax in your code and see what you get). Also
when you click on the + next to the Synthesize-XST more options open you can click on
them individually as well.
9. Double click View RTL Schematic and you can see the schematic block diagram of your
circuit. If you double click the block you can see the gate level circuit. Similarly you can
click on each block and see the basic gate level diagram.
10. Now we need to do pin assignment > click on + next to User constraints > double click
Floorplan Area / IO > Click Yes on the window that opens and another window will open
called the Xilinx PACE. You can see all your IO’s to the left. Now you need to assign the
pins to it. You want to make your inputs switches and your output display as LED’s.
11. Look at your Spartan 6 kit. You can see that there are switches to the bottom and 8
LED’s on top of them. Select any 3 Switches say SW0, SW1, SW2 as your inputs a, b, and
sel respectively. Also from the board manual you can see that next to the switches is a
number i.e. V5, U4, V3 respectively. Note these down and in the Loc position in the
table write these values in front of the respective input. Do the same for outputs and
select two LED’s say W3, Y4.
12. Once done for all the IO’s click save and close the window. This file is saved as .ucf
extension.
13. Now if you click on the – sign next to xc6SLX45-3CSG484 on the left top plane and then
open it again you will see that the .ucf file is also added under the main verilog file.
14. Now double click implement design, Generate Programming File and Configure Target
Device one after the other. Or you can directly double click configure target device and
all steps will execute one after the other.
15. If You get a warning saying No Impact exist just press OK.
16. In the next window press Finish.
17. When impact opens, click on Boundary Scan and you should be able to see your FPGA
device.
18. Now right click on the FPGA box and select assign new configuration file. A browse panel
will open and you will see that a .bit extension file is there. This is your downloadable
file select it and press open.
19. The file has still not downloaded. Right click the FPGA box again select program, in the
window select Apply and then OK.
20. Program has now downloaded.
21. Go to your hardware and test if it is working correctly.
22. You have now made a 2x1 MUX
23. Turn the power to your KIT off and then ON. Is your program still there?
New Example
24. Start a new project in a new folder for the following.
25. Now design a 4X1 MUX and show it to me. (Hint: you can use the 4 IO’s in jumper as
your inputs, 2 switches as your select lines and any 2 leds as your output also remember
from the lecture : assign out = s1 ? (s0 ? i3 : i2) : (s0 ? i1 : i0);). Use jumper wire to give
the IO appropriate low or high signal. Be careful: Do not connect VCC to Ground.
26. Show the 4x1 MUX to me.
27. Now let’s use the always @( ) command.
28. To use always first of all you will have to declare the output as reg so out and outbar
need to be declared as reg. Also if these are to be declared as reg then you will have to
declare them as inputs and output within the module not in the port list. So in the
portlist write all the IO’s names. And within the module declare them as inputs and
outputs
module Mux4(a,b,c,d,s1,s2,out,outbar );
input a,b,c,d,s1,s2;
output out,outbar;
reg out,outbar;
always @ (s1 or s2 or a or b or c or d)
begin
out = s2 ? (s1 ? d : c) : (s1 ? b : a);
outbar=~out;
end
endmodule
29. Do this and show it to me.
30. Close the project and open a new project: Now let us design a 2 bit adder. The code for
this is as under
//-------------------------------------------------------------------------------------------------// Project : Full Adder (1-bit)
// File
: full_adder.v
//--------------------------------------------------------------------------------------------------module full_adder(//Inputs
a,
b,
cin,
//Outputs
sum,
cout
);
//---- Port Declarations ----//
input
a, b, cin;
output sum, cout;
//---- Intermediate signals declaration ----//
reg
sum, cout;
//---- Adder Logic ----//
always@ (a or b or cin)
begin
sum = a ^ b ^ cin;
cout
= (a & b) ^ ((a ^ b) & cin);
end
endmodule
31. Keep note of the code above. This is our full adder Macro that we have created if we
want to make an adder with more bit we can use this.
32. Now close the project and open a new one. Let us make a 2 bit adder another way using
the following code.
Module adder(a,b,sum,cout, cin );
input [1:0] a;
input [1:0] b;
input cin;
output [1:0] sum;
output cout;
reg [1:0] sum;
reg cout;
always @(a,b,cin)
begin
sum= a^b^cin;
cout = (a & b) | ((a ^ b)& cin);
end
endmodule
33. Close this project and open a new one.
34. Now let us make a 4-bit adder using the full adder Macro that we created. The code is
below:
module adder4(a,b,cin,sum,cout);
input [3:0] a;
input [3:0] b;
input cin;
output [3:0] sum;
output cout;
wire
c1, c2, c3;
full_adder fa0 (a[0], b[0], cin, sum[0], c1);
full_adder fa1 (a[1], b[1], c1, sum[1], c2);
full_adder fa2 (a[2], b[2], c2, sum[2], c3);
full_adder fa3 (a[3], b[3], c3, sum[3], cout);
endmodule
35. As you can see this code is using the full_adder Macro that we created for 2 bits. You
will have to copy the Macro file into this folder and make sure that the name of the
Macro is the same.
36. Test this code on your hardware (Hint: Use IO’s on jumper J1 and J2 for your inputs and
one switch for cin, Use Leds for outputs.) Have a look at the RTL schematic as well.
37. Close the project and open a new one.
38. Now let us try to simulate a line tracking robot code. You have 2 sensors on a white line
s1, s2 and two outputs going to wheels w1 and w2. Perform line tracking> If both
sensors are on white line go straight, if robot goes left or right move it back on white
line. If both sensors are off the line stop the robot.
39. Try to do this yourself, verify on your hardware and show it to me.
………………………………….
GIVE UP?? See and test the code on the next page.
module Line(s1,s2,w1,w2 );
input s1;
input s2;
output w1;
output w2;
reg w1,w2;
always @(s1 or s2)
begin
if (s1==1 && s2==1) begin
w1=s1;
w2=s2;
end
else if (s1==0 && s2==1)begin
w1=1; w2=0;
end
else if (s1==1 && s2==0)begin
w1=0; w2=1;
end
else begin
w1=0; w2=0;
end
end
40. Now can you implement the same code using CASE statement? Try it, verify on your
hardware and show it to me (HINT: consult your lecture notes for syntax)
…………………………………………
…………………………………….
……………………………….
…………………………
……………………
……………..
………….
………
….
.
Give up again ?? see the code on the next page.
module Line(s1,s2,w1,w2 );
input s1;
input s2;
output w1;
output w2;
reg w1,w2;
always @(s1 or s2)
begin
case ({s1,s2})
2'b11 : begin w1=1;w2=1; end
2'b01 : begin w1=1;w2=0; end
2'b10 : begin w1=0;w2=1; end
default : begin w1=0;w2=0; end
endcase
end
endmodule
41. Now let’s go one step further. Let’s put a 3rd sensor on your robot. This is a wall
detecting sensor. So the robot will track the line as in normal conditions however if a
wall comes in front of it. The robot should ignore the line tracking commands turn
around and then continue line tracking back. Let your 3rd sensor be S3. If you don’t
understand the problem please ask.
42. Try to do this yourself. Implement it in H/W and show it to me.
..............................................
………………………………………
……………………………………
……………………………….
…………………………….
………………………..
……………………
……………….
…………..
Give up again ?? Try the code on the next page.
module Line(s1,s2,s3,w1,w2 );
input s1;
input s2,s3;
output w1;
output w2;
reg w1,w2;
always @(s1 or s2 or s3)
begin
case ({s1,s2,s3})
3'b110 : begin w1=1;w2=1; end
3'b010 : begin w1=1;w2=0; end
3'b100 : begin w1=0;w2=1; end
3'b111 : begin w1=1;w2=0; end
3'b011 : begin w1=1;w2=0; end
3'b101 : begin w1=1;w2=0; end
default : begin w1=1;w2=0; end
endcase
end
endmodule
HOPEFULLY now you should have an idea of the software ISE environment, how to write basic
codes and implement it on your FPGA hardware.