0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for BCD Counter: Syntax and Example

A bcd counter in Verilog counts from 0 to 9 in binary-coded decimal format and then resets. It uses a 4-bit register and logic to reset after 9. The counter increments on each clock pulse and can be implemented with synchronous reset.
📐

Syntax

The basic syntax for a BCD counter in Verilog includes a 4-bit register to hold the count, a clock input, and a reset input. The counter increments on the rising edge of the clock and resets to 0 when it reaches 9.

  • reg [3:0] count; - 4-bit register to store the BCD value.
  • always @(posedge clk or posedge reset) - Trigger block on clock or reset.
  • if (reset) - Reset count to 0.
  • else if (count == 9) - Reset count to 0 after 9.
  • else - Increment count by 1.
verilog
module bcd_counter(
    input wire clk,
    input wire reset,
    output reg [3:0] count
);

always @(posedge clk or posedge reset) begin
    if (reset)
        count <= 4'b0000;
    else if (count == 4'b1001) // 9 in BCD
        count <= 4'b0000;
    else
        count <= count + 1;
end

endmodule
💻

Example

This example shows a complete BCD counter module that increments from 0 to 9 on each clock pulse and resets asynchronously. It demonstrates how to use a 4-bit register and conditional logic to cycle through BCD digits.

verilog
module bcd_counter(
    input wire clk,
    input wire reset,
    output reg [3:0] count
);

always @(posedge clk or posedge reset) begin
    if (reset)
        count <= 4'b0000;
    else if (count == 4'b1001) // Reset after 9
        count <= 4'b0000;
    else
        count <= count + 1;
end

endmodule

// Testbench to simulate the BCD counter
module testbench();
    reg clk = 0;
    reg reset = 1;
    wire [3:0] count;

    bcd_counter uut(.clk(clk), .reset(reset), .count(count));

    // Clock generation
    always #5 clk = ~clk;

    initial begin
        $monitor($time, " ns: count = %b (%0d)", count, count);
        #10 reset = 0; // Release reset
        #100 $finish;
    end
endmodule
Output
0 ns: count = 0000 (0) 10 ns: count = 0001 (1) 20 ns: count = 0010 (2) 30 ns: count = 0011 (3) 40 ns: count = 0100 (4) 50 ns: count = 0101 (5) 60 ns: count = 0110 (6) 70 ns: count = 0111 (7) 80 ns: count = 1000 (8) 90 ns: count = 1001 (9) 100 ns: count = 0000 (0)
⚠️

Common Pitfalls

Common mistakes when writing a BCD counter include:

  • Not resetting the count after 9, causing it to count beyond BCD range.
  • Using asynchronous reset incorrectly, which can cause glitches.
  • Forgetting to use non-blocking assignments (<=) inside always blocks for sequential logic.
  • Not handling the clock edge properly, leading to incorrect counting.

Always check that the counter resets exactly at 9 and uses synchronous or asynchronous reset as intended.

verilog
/* Wrong way: Using blocking assignment and missing reset condition */
always @(posedge clk) begin
    if (count == 9)
        count = 0; // blocking assignment - wrong
    else
        count = count + 1;
end

/* Right way: Using non-blocking assignment and reset */
always @(posedge clk or posedge reset) begin
    if (reset)
        count <= 0;
    else if (count == 9)
        count <= 0;
    else
        count <= count + 1;
end
📊

Quick Reference

Tips for writing a BCD counter in Verilog:

  • Use a 4-bit register to hold the BCD digit.
  • Reset the counter when it reaches 9 (4'b1001).
  • Use non-blocking assignments (<=) in sequential always blocks.
  • Choose synchronous or asynchronous reset based on your design needs.
  • Test your counter with a simple testbench to verify counting and reset behavior.

Key Takeaways

A BCD counter counts from 0 to 9 using a 4-bit register and resets after 9.
Use non-blocking assignments and proper reset logic inside an always block triggered by clock and reset.
Check that the counter resets exactly at 9 to avoid invalid BCD values.
Test your design with a testbench to ensure correct counting and reset behavior.
Choose synchronous or asynchronous reset depending on your circuit requirements.