Varun
Varun

Reputation: 31

4 bit countetr using verilog not incrementing

Sir,

I have done a 4 bit up counter using verilog. but it was not incrementing during simulation. A frequency divider circuit is used to provide necessory clock to the counter.please help me to solve this. The code is given below

module my_upcount(
    input clk,
    input clr,
    output [3:0] y
    );

 reg [26:0] temp1;
 wire clk_1;

always @(posedge clk or posedge clr)
    begin
      temp1 <= ( (clr) ? 4'b0 : temp1 + 1'b1 );
    end 
assign clk_1 = temp1[26];


reg [3:0] temp;

always @(posedge clk_1 or posedge clr)
    begin
       temp <= ( (clr) ? 4'b0 : temp + 1'b1 );
    end 
assign y = temp;    
endmodule

Upvotes: 0

Views: 1233

Answers (1)

meshlet
meshlet

Reputation: 1507

Did you run your simulation for at least (2^27) / 2 + 1 iterations? If not then your clk_1 signal will never rise to 1, and your counter will never increment. Try using 4 bits for the divisor counter so you won't have to run the simulation for so long. Also, the clk_1 signal should activate when divisor counter reaches its max value, not when the MSB bit is one.

Apart from that, there are couple of other issues with your code:

  • Drive all registers with a single clock - Using different clocks within a single hardware module is a very bad idea as it violates the principles of synchronous design. All registers should be driven by the same clock signal otherwise you're looking for trouble.
  • Separate current and next register value - It is a good practice to separate current register value from the next register value. The next register value will then be assigned in a combinational portion of the circuit (not driven by the clock) and stored in the register on the beginning of the next clock cycle (check code below for example). This makes the code much more clear and understandable and minimises the probability of race conditions and unwanted inferred memory.
  • Define all signals at the beginning of the module - All signals should be defined at the beginning of the module. This helps to keep the module logic as clean as possible.

Here's you example rewritten according to my suggestions:

module my_counter
(
    input wire clk, clr,
    output [3:0] y
);

    reg [3:0] dvsr_reg, counter_reg;
    wire [3:0] dvsr_next, counter_next;
    wire dvsr_tick;

    always @(posedge clk, posedge clr)
        if (clr)
        begin
            counter_reg <= 4'b0000;
            dvsr_reg <= 4'b0000;
        end
        else
        begin
            counter_reg <= counter_next;
            dvsr_reg <= dvsr_next;
        end

    /// Combinational next-state logic
    assign dvsr_next = dvsr_reg + 4'b0001;
    assign counter_next = (dvsr_reg == 4'b1111) ? counter_reg + 4'b0001 : counter_reg;

    /// Set the output signals
    assign y = counter_reg;

endmodule

And here's the simple testbench to verify its operation:

module my_counter_tb;

    localparam
        T = 20;

    reg clk, clr;
    wire [3:0] y;

    my_counter uut(.clk(clk), .clr(clr), .y(y));

    always
    begin

        clk = 1'b1;
        #(T/2);
        clk = 1'b0;
        #(T/2);

    end

    initial
    begin

        clr = 1'b1;
        @(negedge clk);

        clr = 1'b0;
        repeat(50) @(negedge clk);

        $stop;

    end
endmodule

Upvotes: 1

Related Questions