📖 Scenario: You are designing a simple digital circuit that counts numbers up or down based on a control signal. This is useful in many electronics projects like timers, clocks, or simple user interfaces.
🎯 Goal: Create a Verilog module for an up-down counter that changes its count direction based on a control input signal.
📋 What You'll Learn
Create a 4-bit register to hold the count value
Use a clock input to update the count on each rising edge
Use a direction input signal to decide whether to count up or down
Reset the count to zero when reset signal is active
💡 Why This Matters
🌍 Real World
Up-down counters are used in digital clocks, volume controls, and event counters where counting direction changes dynamically.
💼 Career
Understanding counters and direction control is fundamental for hardware design engineers working with digital circuits and FPGA programming.
Progress0 / 4 steps
1
Create the module and declare inputs and outputs
Write a Verilog module named up_down_counter with inputs clk, reset, and dir, and a 4-bit output count. Declare count as a reg type.
Verilog
Hint
Start by declaring the module and its ports exactly as described.
2
Initialize the count register
Inside the module, declare an always block triggered on the rising edge of clk or when reset is high. Inside it, set count to 0 when reset is high.
Verilog
Hint
Use an asynchronous reset inside the always block to set count to zero.
3
Add counting logic based on direction
Inside the always block, add an else branch after the reset condition. Use an if statement to check if dir is 1. If yes, increment count by 1. Otherwise, decrement count by 1.
Verilog
Hint
Use nested if-else inside the always block to update count based on dir.
4
Test the counter output
Add a initial block to display the value of count every time it changes using $monitor. This will help you see the counter output during simulation.
Verilog
Hint
Use $monitor inside an initial block to print count changes during simulation.
Practice
(1/5)
1. What does the direction signal control in an up-down counter in Verilog?
easy
A. The reset state of the counter
B. The speed of the clock signal
C. Whether the counter counts up or down
D. The width of the counter output
Solution
Step 1: Understand the role of the direction signal
The direction signal determines if the counter increments or decrements its value.
Step 2: Relate direction to counting behavior
If direction is high, the counter counts up; if low, it counts down.
Final Answer:
Whether the counter counts up or down -> Option C
Quick Check:
Direction controls count direction = C [OK]
Hint: Direction signal decides count up or down [OK]
Common Mistakes:
Confusing direction with clock speed
Thinking reset controls counting direction
Assuming direction changes output width
2. Which of the following is the correct Verilog syntax to declare a 4-bit up-down counter with direction input?
easy
A. wire [4:0] count; input direction; always @(negedge clk) begin if(reset) count = 0; else if(direction) count = count + 1; else count = count - 1; end
B. reg [3:0] count; input dir; always @(posedge clk) begin if(reset) count <= 0; else if(dir) count <= count + 1; else count <= count - 1; end
C. reg [3:0] count; input dir; always @(posedge clk) begin if(reset) count = 0; else if(dir) count = count + 1; else count = count - 1; end
D. reg [3:0] count; input dir; always @(posedge clk) begin if(reset) count <= 0; else if(dir) count <= count - 1; else count <= count + 1; end
Solution
Step 1: Check variable declarations and types
Count should be a 4-bit reg, direction input is 'dir'.
Step 2: Verify always block and assignments
Use posedge clk, non-blocking assignments '<=' for sequential logic, reset sets count to 0, dir controls increment or decrement.
Final Answer:
Correct syntax with reg, posedge clk, non-blocking assignments, and direction control -> Option B
Quick Check:
Proper reg and non-blocking assignments = A [OK]
Hint: Use reg, posedge clk, and non-blocking <= for counters [OK]
Common Mistakes:
Using wire instead of reg for count
Using blocking '=' in sequential always block
Incorrect clock edge sensitivity
Reversing increment and decrement logic
3. Given this Verilog code snippet for a 3-bit up-down counter with direction control:
A. Using blocking assignment '=' for reset inside always block
B. Missing sensitivity to negedge clk
C. Count should be declared as wire, not reg
D. Direction signal 'dir' is not declared
Solution
Step 1: Check assignment types in sequential always block
Sequential logic requires non-blocking assignments '<=' for all assignments inside always @(posedge clk).
Step 2: Identify inconsistent assignment usage
Reset uses blocking '=' which can cause simulation mismatches; it should use '<=' like other assignments.
Final Answer:
Using blocking assignment '=' for reset inside always block -> Option A
Quick Check:
Use '<=' for all sequential assignments [OK]
Hint: Use non-blocking '<=' in sequential always blocks [OK]
Common Mistakes:
Mixing blocking and non-blocking assignments
Ignoring declaration of signals
Wrong sensitivity list for clock
5. You want to design a 4-bit up-down counter with direction control and synchronous reset in Verilog. The counter should wrap around when it reaches max or min values (i.e., counting up from 15 goes to 0, counting down from 0 goes to 15). Which code snippet correctly implements this behavior?
hard
A. always @(posedge clk) begin
if(reset) count <= 0;
else if(dir) count <= count + 1;
else count <= count - 1;
end