Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Testing verilog code

  1. Sep 28, 2013 #1
    I have a verilog code for a simple 8-bit counter. I'm trying to build a testbench but for some reason it doesn't work. I'm using xilinx and when I run the simulation, the inputs work but the output doesn't work. It stays as XXX. Here is my verilog code and testbench.

    Code (Text):

    module counter(enable, reset, clk, out, AN, style);

    input style; //to count up or down
    input clk;
    input reset;
    input enable;
    output [6:0] out; //output to display

    reg[3:0] first; //to hold the output for first seven-seg
    reg[3:0] second;//to hold the outputfor second seven-seg
    reg[24:0] CLKCNTR;  //clock counter
    output [3:0] AN;//to indicate which seven-seg to use

        always @(posedge clk)begin//mak it count when the clock ticks
           
            CLKCNTR = CLKCNTR+1;    //increment the clock counter by one until
            if (CLKCNTR==25000000) //it reaches 25000000
            begin
                CLKCNTR=0;  //reset the counter to loop
                if (reset)      //occurs only when reset is high
                begin
                    first=0;        //reset seven segment displasy if
                    second=0;   //reset is high
                end
               
                else if (enable)   
                begin
                    if (style)  //if counting up
                    begin
                        first = first+1;//increment first digit
                   
                        if(first==10) //if it reaches 10, reset and increment next digit
                        begin
                            first=0;
                   
                            second = second+1; 
                   
                            if(second==6) //if second digit reaches 6(one minute), reset
                                second=0;
                   
                        end
                    end
                   
                    else if (!style)//if counting down
                    begin
                        if (first>0)//decrement the first digit unitl it reaches zero
                            first=first-1;
                        else
                        begin
                            first=9;
                            if (second>0)
                                second=second-1;
                            else
                                second=5;
                        end
                    end
                end
             end
        end
       
        //instantiate the display module with the inputs and output
        display D1(.clk(clk), .out(out),.AN1(AN), .ones(first), .tens(second));
       
       
    endmodule


    module display(clk, out,AN1, ones, tens);


    input clk;
    output reg[6:0] out;
    //output reg[6:0] out2;
    input [3:0]ones; //first digit(seven segment display)
    input [3:0]tens; //second digit(seven segment display)
    output reg [3:0] AN1; //to tell which seven segment display is to be turned on
    reg[20:0] DSPCNTR; //display counter

     initial begin
        AN1[3:0] =4'b1011;//initialize the seven-seg displays
        end
        always@(posedge clk)
        begin
            DSPCNTR = DSPCNTR +1;//increment the counter of display counter until it reaches 25MHz
            if(DSPCNTR == 250000)//that way the seven-segs are refreshed and we are able to see them change
            begin
                DSPCNTR = 0; //reset counter
               
                AN1[2]=~AN1[2];
                AN1[1]=~AN1[1];
                if (AN1[1])
                begin
                    case (ones)//case for first digit
                            0: out=7'b1000000;
                            1: out=7'b1111001;
                            2: out=7'b0100100;
                            3: out=7'b0110000;
                            4: out=7'b0011001;
                            5: out=7'b0010010;
                            6: out=7'b0000010;
                            7: out=7'b1111000;
                            8: out=7'b0000000;
                            9: out=7'b0010000;
                        default: out=7'b1111111;
                        endcase
                end
               
              else if (AN1[2])//case for second digit
                begin
                    case (tens)
                            0: out=7'b1000000;
                            1: out=7'b1111001;
                            2: out=7'b0100100;
                            3: out=7'b0110000;
                            4: out=7'b0011001;
                            5: out=7'b0010010;
                            6: out=7'b0000010;
                            7: out=7'b1111000;
                            8: out=7'b0000000;
                            9: out=7'b0010000;
                        default: out=7'b1111111;
                       
                    endcase    
                end
             
            end
        end
       
    endmodule

     
    testbench

    Code (Text):


    module counter_tb;

        // Inputs
        reg enable;
        reg reset;
        reg clk;
        reg style;

        // Outputs
        wire [6:0] out;
        wire [3:0] AN;

        // Instantiate the Unit Under Test (UUT)
        counter uut (
            .enable(enable),
            .reset(reset),
            .clk(clk),
            .out(out),
            .AN(AN),
            .style(style)
        );

        initial begin
            // Initialize Inputs
            enable = 0;
            reset = 0;
            clk = 0;
            style = 0;

            // Wait 100 ns for global reset to finish
            #100;
           
            // Add stimulus here
        #3 reset =1;
        #2reset = 0;
        #2 style = 1;
        #2 enable = 1;
        #100 enable = 0;
        #4 reset = 1;
        #4 reset = 0;
        end

    always begin
        #1 clk = ~clk;  //clock toggles every strike
    end

    endmodule
     
    I can't seem to find the reason why the output is no being displayed. I have tested someone else's code and the same happened. Could someone kindly give me a clue on what I'm doing wrong?
     
    Last edited: Sep 28, 2013
  2. jcsd
  3. Sep 28, 2013 #2

    meBigGuy

    User Avatar
    Gold Member

    I think you are not resetting the counter. X + 1 = X

    On another note, when you synthesize RTL flops, they should be of the form
    // for sync reset
    Code (Text):
    always @ (posedge clk) begin
       if (reset) begin
          counter <= 0;
          //always reset EVERYTHING in this block here ---- get in the habit
       end else begin
          if (enable) begin
             counter <= counter + 1;
          end
       end
    end
     
    //for async reset

    Code (Text):
    always @ (posedge clk or posedge reset) begin
       if (reset) begin
          counter <= 0;
          //always reset EVERYTHING in this block here ---- get in the habit
       end else begin
          if (enable) begin
             counter <= counter + 1;
          end
       end
    end
    The separation of the reset block is important in some cases, expecially if you do gate level sims after synthesis. For "normal" synthesis tools you need to follow that structure. Again, get in the habit.
     
  4. Sep 28, 2013 #3
    I don't think I'm following you completely. If there is a block describing the procedure to be done when reset happens, why do I have to check at the edge of reset?
     
  5. Sep 28, 2013 #4

    meBigGuy

    User Avatar
    Gold Member

    Sorry, maybe I confused you. I showed two different examples, one for sync reset flops and one for async reset flops. In order to map (synthesize) to an async reset flop you need to follow the form of the second example.

    The first example is good form for synchromous reset in clocked blocks, but is not mandatory. It is structured that way because reset should be the highest priority. This eliminates problems with X at the beginning of simulation (X propagation) that can happen in gate-level simulations. Sometimes thare are two resets. A power-on reset at the beginning of operation, and a soft-reset that can occur anytime. Sometimes you want them to do different things.

    But there is another problem in your design. Simulations begin with all elements set to X.

    CLKCNTR starts as X. When you add 1, it is still X. It will always be X. So reset will never be seen.
     
  6. Sep 28, 2013 #5
    I don't see how the reset would never be seen. I tried initializing CLKCNTR but I get the same result. The compiler doesn't give me any warnings/errors about that. Also. I was able to test my code on an FPGA and it worked perfectly. I don't understand why it wouldn't work with the simulator. Here is a screenshot from the simulator.

    I also tried initializing the outputs but they remain with that value all the way through.
     

    Attached Files:

  7. Sep 29, 2013 #6

    meBigGuy

    User Avatar
    Gold Member

    The x problem is a simulation thing, since x doesn't exist in real life. Show the values for all the internal signals.

    Try initializing DSPCNTR
     
  8. Sep 29, 2013 #7
    to expand on what meBigGuy wrote, you never initialize CLKCNTR. It is defined as a register, but it's initial value is never given -- you start incrementing it right after the Always statement, without initializing it first. Your reset block is never seen because the counter never increments from X in the first place -and your if(reset) test only is seen if CLKCNTR==25000000. Like he said, you are better off always starting with an initialization clause within the Always blocks that resets all registers to their initial conditions (he showed two ways of doing this)

    I would suggest the following:

    always @ (posedge clk)
    if (reset || (CLKCNTR==25000000) ) // synchronous reset under either condition....
    begin
    counter <= 0;
    end
    else if (reset)
    begin
    first <=0;
    second <=0;
    end
    else if (enable)
    begin
    counter <= counter + 1;
    end
    end //always block
     
    Last edited: Sep 29, 2013
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Testing verilog code
  1. Verilog and gtkwave? (Replies: 2)

Loading...