Verilog simulation in Xilinx

In this post, I am going to show you how to simulate a Verilog code in Xilinx ISE. I have included every step with an image so that the user can easily understand every step clearly. 

Ok let's begin 
I am using Xilinx ISE version 14.2 
You can have your own version of Xilinx or ModelSim or MultiSim HDL Simulator but the methodologies for implementing a Verilog code within them might be different. 

For this post its version 14.2 

First of all click on the desktop icon ISE Design Suite 14.2 

A Window will open. After the window opens, which might take some time depending on your system configuration. Click on the tab "New Project" as shown below. 

Enter the name of the project in the first field. Be sure that the location where you are going to save your project is having permission to write. You cannot save at a location that has only read only permission. 
Click "Next" and select the "Device" field as Spartan 6 because that's what I am going to use within this post.

Now click "Finish".

Now on the top left corner, you'll see two views. One of them states "Implementation" which is for finalizing implementing RTL schemaric of code and to find its parameters like heat, speeds, timings etc. The other view states "Simulation". We will start with the implementation first. Click on the  "Implementation" radio button 

Under your project name you will see another folder structure named xclscf something like that. Right click and click on new source.

Select "Verilog Module" and give the module a name. Click next when done. You can leave the input and output ports blank or you can enter the ports if you are sure about your code. As I am never sure of my code, I will leave it blank. I'll insert the input and output ports within the code itself.

For this post, I am implementing my own SPI which is the serial peripheral interface in this simulation. To have a look on my SPI simulation and code, Click Here.

A window on the right side will pop out as shown below. It will have some predefined comments, describing the date, user and creator of project. It's just the time and owner stamp. It's upto you whether you want to keep it or not.

I removed the time and creator stamp and pasted my own Master code from my SPI post. I have also added Slave code using the same method as I showed above to add a new "Verilog Module". Now its time to explain in layman terms about module, testbench, and datapath. I am expecting all students to have some classes about Verilog coding and understanding of wires, outputs, and circuits.

Let us consider an IC which has components like register file, multiplexors, adder, subtractor etc as shown below. 

As per the above diagram we have a component A and component B. 
For each component, as shown above, for A and for B, will have to declare a module or specifically saying a Verilog module like below. For module A, we are having an input present at pin 2 and an output present at pin 7. Similarly, for module B we have an input from pin 3 and from A and a single output at pin 6. The Verilog code for the module or the component a using the description above will be as follows

module A(in_pin2, out_pin7, out_to_B);
input in_pin2,
output out_pin7,
output out_to_B;
initial begin

module B(in_pin3, in_from_A, out_pin6);
input in_pin3,
input in_from_A,
output out_pin6,
initial begin

This is how we are going to add Verilog code for master as well as the slave for our simulation. 

No coming to the next question. What is a datapath?
Basically a data path includes the connection between various components inside the Integrated circuit. For example, in the above diagram, you can easily see components A and B are linked with each other using the red coloured wire and the wire which is attached to pin 7. Now, remember, for data path you have to include every wire that is connected between various models which are not present at the input or the output along with wires that you want to see as your output from the IC. 

All the connection between various models which are not the input port or the output port have to be declared as wires. In the above diagram,  component A has two internal wires with  the component B, the first one is the red wire and the second wire is connected with pin 7. Now I want to see the input of component A and component B as well as the output of component A and component B. 

module Datapath(in2,in3, out7, out6);
input int2, in3;
output out6, out7;
wire red_wire;
A Component_A(in2, out7, red_wire);
B Component_B(in3, red_wire, out6);

The basic syntax to instantiate a componet is 

Component Name Variable_Name (PORTS IN ORDER)

Here component name is A. Its variable name is "Component_A" and ports which have to be in order as they were declared in A. Have a close look at the ports of componet A within the brackets. 

(in_pin2, out_pin7, out_to_B);

The first port is in_pin2 which is an input pin attached to datapath port in2. The second port is out_pin7 which is connected to the out7 pin of the datapath. The third port is "out_to_B" which is an internal wire in datapath connected to "red_wire" in the datapath. One simply cannot assign any datapath port while instantiating a component. It has to be in order. Input port of IC is pin 2 which is declared as "in2" in the datapath. We have to connect this to component A's input which is "in_pin2" which is the first port declared within the brackets. Thus, while instantiating component A, we have to assign correct datapath port to the correct position of A. We cannot instantiate like this below

A Component_A(out7, in2, red_wire);

The first port of A, which is reserved to be input from pin 2 has to be the input from pin 2 but we have assigned "out7" to the input of A which is completely wrong. Similarly, we have assigned input from pin2 (in2) to the output of component A. The red wire is, however, assigned correctly to the 3rd position which points to output to B of A.

Now we have instantiated component A and component B within the data path, saving the data path module will automatically assign or basically put the module A and module B within the data path module. This shows that the models are being instantiated under the datapath module as shown in the below image. Now refer to the IC diagram above. As you can see, both the components lies within the IC. The IC is our datapath here hence, component A and B must lie within it.

Now coming to the tesbench part. A testbench is an environment which is used to provide input to our system and get the output from this system. Just take connecting a CRO to a transistor, where we can see the output from a transistor. Similarly, we can see our simulation through the testbench. One should always remember that all the input ports in the testbench have to be of Register type and all the outputs of have to be of wire type unlike in module where input has to be of wire type and the output can be wire as well as register.

To create a testbench, click on the "New source" and this time instead of selecting Verilog module select Verilog text fixture. It will show you some options of the available modules from your project on which you have to start your testing. We have to test the entire IC not specifically to the component A or component B. Select the data path module which is to be tested via Verilog text fixture or test bench. Xilinx will automatically assign ports according to the input and output ports defined in the data path module. Do remember that the internal wires are not attached with the testbench. The internal wire is that wire which is neither connected to the output nor to the input.
Only the input and the output of the data path will be connected to the test bench. All the input and output of the data path are the same to which we have to provide input and from which we have to derive the output. 

To simulate, we have to select the view "Simulation' which was earlier set to "Implementation". The moment you will set it to "Simulation", in the below menu you will get options like this.

Double click on "Behavioral Check Syntax" to check the logic for errors. Wish for a green colored tickmark beside. If successful, double-click on "Simulate Behavioral Model" to simulate and wait for the results. 

Now to see a specific port which is NOT present in the testbench can be selected from the leftmost panel from "Test" and "glbl" menu. Select the port and press CTRL + W and then "Re-Launch".



  1. Hi Shashi,
    Can you also attach a simple testbench code for the SPI master and slave you wrote ?


Post a Comment

Popular posts from this blog

SPI Working with Verilog Code

Verilog Code for I2C Protocol

SR Flip Flop Verilog Code