Electronic – How to use “AND” statement in Verilog

counterfpgaliberoverilogxilinx

I am trying to create a counter that starts counting when a start signal goes from 0 to 1. Then, I want the counter to keep counting until both the start and stop signal are 1. Once both signals are 1 the counter should reset to 0.

I am confident that the reason my counter does not reset is because of the "else if (start && stop)" statement.

Thanks for the help!

Here is my code:

module count2     (
out  ,   // output of counter 
start ,   // start pulse 
stop,     // stop pulse
clk  ,  // clock input
reset    // reset input
);

input start, stop, clk, reset;
output out;

reg [7:0] out;
reg [7:0] counter;

always @ (posedge clk)
if (reset)
begin
    counter <= 8'b0;
end
else if (start)
    counter <= counter + 1; 
else if (start && stop)
begin 
    counter <= 8'b0;
end
endmodule 

Here is my tesetbench:

`timescale 1ns/100ps

module count2_tb;

// parameter SYSCLK_PERIOD = 20;// 50MHZ

reg clk_1;
reg start_1;
reg stop_1;
reg reset_1;

wire [7:0] out_1; 

initial
begin
    clk_1 = 1'b0;
    start_1 = 1'b0;
    stop_1 = 1'b0;
    reset_1 = 1'b1;
    #20;
    reset_1 = 1'b0;
    #20;
    start_1 = 1'b1;
    #50;
    stop_1 = 1'b1;
    #50;
    $stop;
end

//////////////////////////////////////////////////////////////////////
// Clock Driver
//////////////////////////////////////////////////////////////////////
always
    #5 clk_1 = ~clk_1;
//////////////////////////////////////////////////////////////////////
// Instantiate Unit Under Test:  counter
//////////////////////////////////////////////////////////////////////
count2 count2_0 (
    // Inputs
    .start(start_1),
    .stop(stop_1),
    .clk(clk_1),
    .reset(reset_1),

    // Outputs
    .out( out_1 )
);

endmodule

Here is my waveform output from ModelSim:

enter image description here

Best Answer

The conditions in an if-else if chain are evaluated sequentially, and once one of them matches, the other ones will not be checked. So when you have:

else if (start)
    counter <= counter + 1; 
else if (start && stop)

it sees that start is 1, and runs the counter + 1 assignment. It never checks if stop is also 1.

To fix it, you have 2 options:

  • Reverse the order of the checks (check start && stop before checking start alone), or
  • Change the first condition so that it is false when stop is 1, like if (start && !stop)