Tutorials

Learn More

In asynchronous counter, within the counter output of one flip flop stage, is driven to the clock pin of the next flip flop stage. Thus, the transition of the first stage ripples till the last flip-flop stage. Hence, it is also known as the “Ripple Counter” or “Serial Counter”. In the asynchronous counter, individual flip-flop stages are triggered with the different clocks. Due to this, it is slower when compared with a synchronous counter. It is easy to design with less hardware requirement.

Disadvantages

  1. Slow operation when compared with a synchronous counter.
  2. High propagation delay

Block Diagram

asynchronous counter

4-bit Up-Down Asynchronous Counter Verilog Code

module JK_flipflop (
  input clk, rst_n,
  input j,k,
  output reg q, q_bar
  );
  
  always@(posedge clk or negedge rst_n) begin // for asynchronous reset
    if(!rst_n) q <= 0;
    else begin
      case({j,k})
        2'b00: q <= q;    // No change
        2'b01: q <= 1'b0; // reset
        2'b10: q <= 1'b1; // set
        2'b11: q <= ~q;   // Toggle
      endcase
    end
  end
  assign q_bar = ~q;
endmodule

module updown_selector(input q, q_bar, bit up, output nclk);  
  assign nclk = up?q_bar:q;
endmodule

module asynchronous_counter #(parameter SIZE=4)(
  input clk, rst_n,
  input j, k,
  input up,
  output [3:0] q, q_bar
);
  wire [3:0] nclk;
  genvar g;
  /*
  // Up Counter (at output q)
  JK_flipflop jk1(clk, rst_n, j, k, q[0], q_bar[0]);
  JK_flipflop jk2(q_bar[0], rst_n, j, k, q[1], q_bar[1]);
  JK_flipflop jk3(q_bar[1], rst_n, j, k, q[2], q_bar[2]);
  JK_flipflop jk4(q_bar[2], rst_n, j, k, q[3], q_bar[3]);
  
  // Down Counter (at output q)
  JK_flipflop jk1(clk, rst_n, j, k, q[0], q_bar[0]);
  JK_flipflop jk2(q[0], rst_n, j, k, q[1], q_bar[1]);
  JK_flipflop jk3(q[1], rst_n, j, k, q[2], q_bar[2]);
  JK_flipflop jk4(q[2], rst_n, j, k, q[3], q_bar[3]);
  
  // Up and Down Counter (at output q)
  JK_flipflop jk1(clk, rst_n, j, k, q[0], q_bar[0]);
  updown_selector ud1(q[0], q_bar[0], up, nclk[0]);
  
  JK_flipflop jk2(nclk[0], rst_n, j, k, q[1], q_bar[1]);
  updown_selector ud2(q[1], q_bar[1], up, nclk[1]);
  
  JK_flipflop jk3(nclk[1], rst_n, j, k, q[2], q_bar[2]);
  updown_selector ud3(q[2], q_bar[2], up, nclk[2]);
  
  JK_flipflop jk4(nclk[2], rst_n, j, k, q[3], q_bar[3]);
  */
  
  // Using generate block
  JK_flipflop jk0(clk, rst_n, j, k, q[0], q_bar[0]);
  generate
    for(g = 1; g<SIZE; g++) begin
      updown_selector ud1(q[g-1], q_bar[g-1], up, nclk[g-1]);
      JK_flipflop jk1(nclk[g-1], rst_n, j, k, q[g], q_bar[g]);
    end
  endgenerate
endmodule

Testbench Code

module tb;
  reg clk, rst_n;
  reg j, k;
  reg up;
  wire [3:0] q, q_bar;
  asynchronous_counter(clk, rst_n, j, k, up, q, q_bar);
  
  initial begin
    clk = 0; rst_n = 0; 
    up = 1;
    #4; rst_n = 1;
    j = 1; k = 1;
    #80;
    rst_n = 0;
    #4; rst_n = 1; up = 0;
    #50;
    $finish;
  end
  always #2 clk = ~clk;

  initial begin
    $dumpfile("dump.vcd"); $dumpvars;
  end
endmodule

Waveform

asynchronous counter waves