SourceRTL Design Directory

Up/Down Counter: An Overview

An up/down counter, also known as a bidirectional counter, is a sequential digital circuit that can increment(count up) of decrement(count down) its values. The control signal dictates the direction of the counter. These counters are widely used in digital design for counting purposes such as in frequency division, event counting, etc.

Applications

  1. Digital Clocks: To count seconds, minutes, and hours.
  2. Frequency Dividers: To divide the frequency of a clock signal.
  3. Event Counters: To count occurrences of events in a digital system.
  4. Position Encoders: In robotics to keep track of position.

Design: 4-bit Up/Down Counter

A 4-bit binary up/down counter counts from 0 (0000 in binary) to 15 (1111 in binary). When in up-counting mode, the counter increases its value by 1 with each clock pulse. Starting from 0000, it counts up to 0001, 0010, 0011, and so on, until it reaches 1111. After reaching 1111, the next increment will cause the counter to wrap around and start again from 0000. Similarly, when in down-counting mode, the counter decreases its value by 1 with each clock pulse. Starting from 1111, it counts down to 1110, 1101, 1100, and so on, until it reaches 0000. After reaching 0000, the next decrement will cause the counter to wrap around and start again from 1111. A control signal (often labeled as UP/DOWN) determines the counting direction. When the control signal is high (1), the counter operates in up-counting mode. When the control signal is low (0), the counter operates in down-counting mode.

Verilog Code: 4-bit Up/Down Counter

module up_down_cntr #(parameter N = 4)(/*AUTOARG*/
   // Outputs
   dout,
   // Inputs
   up, clk, rst
   );
   // Outputs
   output [N-1:0] dout;
   // Inputs
   input	  up;
   input	  clk;
   input	  rst;


   logic [N-1:0] cntr;

   /*AUTOREG*/
   /*AUTOWIRE*/

   always_ff@(posedge clk) begin
      if(rst)
        cntr <= 0;
      else
        if(up)
          cntr <= cntr + 1;
        else
          cntr <= cntr - 1;
   end

   assign dout = cntr;

endmodule