0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for 4 Bit Down Counter: Syntax and Example

A 4 bit down counter in Verilog counts down from 15 to 0 using a reg [3:0] variable updated on the posedge of a clock. The counter decreases by 1 each clock cycle and resets to 15 when it reaches 0.
📐

Syntax

The basic syntax for a 4 bit down counter uses a reg [3:0] to hold the count value. The counter updates on the rising edge of the clock (posedge clk) and optionally resets asynchronously or synchronously.

  • reg [3:0] count; declares a 4-bit register to store the count.
  • always @(posedge clk or posedge reset) triggers the block on clock or reset.
  • if (reset) sets the count to 15 (max 4-bit value) on reset.
  • else count <= count - 1; decreases the count by 1 each clock cycle.
verilog
reg [3:0] count;
always @(posedge clk or posedge reset) begin
    if (reset)
        count <= 4'b1111; // reset to 15
    else
        count <= count - 1;
end
💻

Example

This example shows a complete 4 bit down counter module with clock and reset inputs. The counter starts at 15 and counts down to 0, then wraps back to 15.

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

always @(posedge clk or posedge reset) begin
    if (reset)
        count <= 4'b1111; // start at 15
    else if (count == 4'b0000)
        count <= 4'b1111; // wrap to 15
    else
        count <= count - 1;
end

endmodule
Output
At each clock pulse, count outputs: 15, 14, 13, ..., 1, 0, then repeats from 15.
⚠️

Common Pitfalls

Common mistakes when writing a 4 bit down counter include:

  • Not resetting the counter properly, causing it to start at an unknown value.
  • Forgetting to wrap the count back to 15 after reaching 0, which can cause underflow.
  • Using blocking assignments (=) inside always blocks triggered by clock edges, which can cause simulation mismatches.

Always use non-blocking assignments (<=) for sequential logic and handle reset and wrap conditions explicitly.

verilog
/* Wrong way: missing wrap and using blocking assignment */
always @(posedge clk or posedge reset) begin
    if (reset)
        count = 4'b1111; // blocking assignment
    else
        count = count - 1; // no wrap check
end

/* Correct way: non-blocking and wrap check */
always @(posedge clk or posedge reset) begin
    if (reset)
        count <= 4'b1111;
    else if (count == 4'b0000)
        count <= 4'b1111;
    else
        count <= count - 1;
end
📊

Quick Reference

Tips for writing a 4 bit down counter in Verilog:

  • Use reg [3:0] for the counter variable.
  • Trigger updates on posedge clk and handle asynchronous or synchronous reset.
  • Use non-blocking assignments (<=) inside always blocks for sequential logic.
  • Check for zero and wrap the count back to 15 to avoid underflow.
  • Test your counter with a testbench to verify correct counting and reset behavior.

Key Takeaways

Use a 4-bit register and update it on the clock's rising edge to create a down counter.
Always reset the counter to 15 to start counting down correctly.
Wrap the count back to 15 when it reaches zero to avoid underflow.
Use non-blocking assignments inside clocked always blocks for correct simulation.
Test your design with a testbench to ensure proper counting and reset.