Verilog Coding Tips and Tricks: verilog tutorial
Showing posts with label verilog tutorial. Show all posts
Showing posts with label verilog tutorial. Show all posts

Tuesday, November 17, 2015

How to Simulate your Verilog codes Online?

Have you wondered how useful it would be to have an online Verilog compiler and simulator? How useful it would be to just copy and paste the code to a web simulator and verify the design without going through all the detailed steps in your computer? Then you are lucky!

EdaPlayground developed by Duolos is the answer. This web service allows you to test your Verilog,System Verilog or Python codes online for free. You can log in to the service with a Google or Facebook account and start compiling and simulating your design. 

The service also allows you to save your designs for later reference and lets you share them with a simple link. 

There is an option to see the simulation waveform too. But for this you have to add the following two lines in your testbench "initial" statement.

    $dumpfile("dump.vcd");
    $dumpvars(1, test);   //replace test with the testbench module name

One more useful feature worth mentioning is the Collaborate option. This lets you share the design workspace with a fellow coder so that you can learn from each other. You can chat with your friend and create the design together. But note that the feature is still in beta mode.

I wouldn't explain here how to use this web service in depth. Because they have explained it well, through this Youtube video.



Happy Designing!!!


Thursday, November 12, 2015

How to Write a simple Testbench for your Verilog Design

Once you complete writing the Verilog code for your digital design the next step would be to test it. First we have to test whether the code is working correctly in functional level or simulation level. A program written for testing the main design is called Testbench

In this post I want to show you, how to write a very simple testbench. Lets consider two types of designs. One without any clock(purely combinational) and one with clock(contains synchronous elements).

Without Clock:

The module takes two inputs A and B and returns the XOR of A and B as output on port C.

//XOR module
module test(A,B,C);

    input [7:0] A,B;
    output [7:0] C;
    
    assign C = A ^ B;
    
endmodule

The testbench code for the above module is given below. I have commented it well enough to show you the important sections.

//testbench module.
//Its a testbench, so we dont have any inputs or outputs for this module.
module tb;

    // Declare the Inputs as Reg's
    reg [7:0] A;
    reg [7:0] B;

    // Declare the Outputs as wire's
    wire [7:0] C;

    // Instantiate the design you want to test.
    //Read this for instantiation methods
    test uut (
        .A(A), 
        .B(B), 
        .C(C)
    );

//We will apply the inputs here.
    initial begin
        // Apply the first set of Inputs
        A = 100;
        B = 40;
        #100; //wait for some time before we apply the next input.
        //Apply the 2nd set of inputs and so on...
      A = 10;
        B = 30;
        #100; //wait for some time before we apply the next input.  
        A = 255;
        B = 0;
        #100;
    end
//end the simulation inputs here.   

//In case your simulator doesnt have a simulation waveform then display the inputs and outputs
//using display system command.
//whenever there is a change in A or B execute the always block.
always@(A,B)
    $display("A = %b,B = %b,C = A xor B = %b",A,B,C);
    
endmodule


The following lines will be printed after the codes were simulated:

A = 01100100,B = 00101000,C = A xor B = xxxxxxxx
A = 00001010,B = 00011110,C = A xor B = 01001100
A = 11111111,B = 00000000,C = A xor B = 00010100

I used Xilinx ISE 13.1 for simulation and I got the following waveform. For bigger designs with tons of variables and internal signals, I prefer using simulation waveform to debug the design.


With Clock:

For simplicity I will just add a clock to the above module. The XOR operation will take place at every positive edge of the clock. 

//XOR module with clock
module test(CLK,A,B,C);

    input CLK;
    input [7:0] A,B;
    output [7:0] C;
    reg [7:0] C;
    
    always@ (posedge CLK)
        C = A ^ B;
    
endmodule


The testbench for this type is almost the same as the old one. Just that, we have to add a clock here. Also we have generate a clock which keeps alternating between 0 and 1 till the end of simulation.


//testbench module.
//Its a testbench, so we dont have any inputs or outputs for this module.
module tb;

    // Declare the Inputs as Reg's
    reg [7:0] A;
    reg [7:0] B;
    reg CLK;

    // Declare the Outputs as wire's
    wire [7:0] C;

    // Instantiate the design you want to test.
    //Read this for instantiation methods
    test uut (
        .CLK(CLK),
        .A(A), 
        .B(B), 
        .C(C)
    );

//Generate the clock here:
    initial CLK = 0;  //initialize the clock value to zero
     //toggle the clock value every 10 ns. 
     //So the clock has a clock period of 20 ns.
    always #10 CLK = ~CLK; 

//We will apply the inputs here.
    initial begin
        // Apply the first set of Inputs
        A = 100;
        B = 40;
        #100; //wait for some time before we apply the next input.
        //Apply the 2nd set of inputs and so on...
      A = 10;
        B = 30;
        #100; //wait for some time before we apply the next input.  
        A = 255;
        B = 0;
        #100;
    end
//end the simulation inputs here.   

//In case your simulator doesnt have a simulation waveform then display the inputs and outputs
//using display system command.
//whenever there is a change in A or B execute the always block.
always@(A,B)
    $display("A = %b,B = %b,C = A xor B = %b",A,B,C);
    
endmodule


The display system function outputs the same results as in the last case. The simulation waveform obtained in Xilinx ISE 13.1 is pasted below:


Note how the output port C is only updated at the positive edge of the clock and not right after the change of inputs.

Notes:-

As with everything else, you can get creative with testbench designs too. For complex designs you might have to read the inputs from the files and write the outputs to the files. Here I just wanted to show you something very basic. I will cover many more aspects of testbench design in coming posts.

Tuesday, November 10, 2015

Concatenation Operator in Verilog

Concatenation is generally used for combining two or more vectors to form a single vector. But in Verilog, concatenation operator can be used to either join two or more vectors or split a vector into small sub-vectors.

{ and } together form the concatenation operator in Verilog.

I will show you some examples, to give you a practical idea.

Combing two or more vectors to form a single vector:

//Declare the registers
reg [7:0] c;  //8 bit vector
reg [4:0] a = 5'b11111;  //5 bit vector
reg [2:0] b = 3'b000;    //3 bit vector


//First way to concatenate
    c = {a,b};            // c = "11111000"                       
    c = {b,a};            // c = "00011111"
    
//Replicate a vector multiple times by using {{}}   
// {a{b}} means 'b' replicated 'a' times.

// size of "1" is not mentioned. so its taken as a 32 bit integer.
    c = {{1}};           // c = "00000001"

// size of "1" is mentioned and its replicated 8 times. 
    c = {8{1'b1}};       // c = "11111111"
    
//the replicated part will be added to Least significant bits. MSB is padded with zeros.    
    c = {4{1'b1}};       // c = "00001111"
   
//Note that MSB is padded with zeros again  
    c = {{2'b10}};       // c = "00000010"

//"10" is replicated 4 times.   
    c = {4{2'b10}};       // c = "10101010"  

//replicate "110" eight times and take the least significant 8 bits.    
    c = {8{3'b110}};      // c = "10110110"

// Compilation error. Multiple concatenating is not allowed.
    c = {2{4{1'b1}}};     

Splitting a vector to smaller vectors:

//Declare variables
reg [7:0] e = 8'b10110110;  //8 bit vector
reg [4:0] d;  //5 bit vector
reg [2:0] a,b,c;    //3 bit vector

//splitting up a vector to two vectors. 
    {a,d} = e;               // a = "101" and d = "10110"   

//splitting up a vector to three vectors.   
//Least significant vectors(right hand side) is filled first.
// remaining vectors are assigned zero.
    {a,b,c} = 8'b11111111;   // a = "011" , b = "111" , c = "111"

//splitting up a vector to three vectors.   
//10 times "10" is replicated.  
    {a,b,c} = {10{2'b10}};   // a = "010" , b = "101" , c = "010"

I hope the concept of concatenation operator is clear now. A clear understanding of this might save you, lots of typing, when you are implementing your Verilog design.