📖 Scenario: You are designing a simple digital circuit using Verilog. To make sure your design works well when converted to hardware (synthesized), you need to follow best practices in coding.This project will guide you step-by-step to write a synthesizable Verilog module that counts up to a certain number.
🎯 Goal: Build a synthesizable Verilog counter module that counts from 0 up to a given limit and then resets. You will learn how to write clear, synthesis-friendly code with proper clock and reset handling.
📋 What You'll Learn
Create a Verilog module with input clock and reset signals
Use a register to hold the counter value
Implement synchronous reset and counting logic
Use non-blocking assignments inside always blocks
Print the counter value in simulation to verify behavior
💡 Why This Matters
🌍 Real World
Counters are basic building blocks in digital circuits used in timers, event counters, and state machines.
💼 Career
Understanding synthesizable Verilog coding is essential for FPGA and ASIC design engineers to create reliable hardware.
Progress0 / 4 steps
1
DATA SETUP: Define the module and inputs
Write a Verilog module named counter with inputs clk and rst (both 1-bit). Also declare an output count as a 4-bit register.
Verilog
Hint
Start by declaring the module and its ports exactly as described.
2
CONFIGURATION: Declare a parameter for the maximum count
Inside the counter module, declare a parameter named MAX_COUNT and set it to 10.
Verilog
Hint
Use the parameter keyword to define a constant inside the module.
3
CORE LOGIC: Implement synchronous reset and counting
Add an always block triggered on the rising edge of clk. Inside it, use an if statement to check if rst is high. If yes, set count to 0. Otherwise, if count is less than MAX_COUNT - 1, increment count by 1. Use non-blocking assignments (<=) for count updates.
Verilog
Hint
Use an always @(posedge clk) block with non-blocking assignments for synthesis-friendly sequential logic.
4
OUTPUT: Add a testbench to simulate and print the counter
Write a testbench module named tb_counter. Instantiate the counter module. Generate a clock signal clk toggling every 5 time units. Apply a reset pulse for 10 time units at start. Run the simulation for 100 time units. Use $monitor to print the time and count value whenever it changes.
Verilog
Hint
Use a testbench with clock toggling every 5 units, reset active for first 10 units, and $monitor to print count changes.
Practice
(1/5)
1. Which of the following is a best practice for writing combinational logic in Verilog for synthesis?
easy
A. Leave some outputs unassigned to infer latches.
B. Use non-blocking assignments (<=) inside an always @(*) block.
C. Use delays like #5 to model timing.
D. Use blocking assignments (=) inside an always @(*) block.
Solution
Step 1: Understand combinational logic coding
Combinational logic should be written using blocking assignments (=) to ensure correct immediate updates within the always @(*) block.
Step 2: Identify synthesis best practices
Using non-blocking assignments or delays in combinational blocks can cause unintended behavior or non-synthesizable code.
Final Answer:
Use blocking assignments (=) inside an always @(*) block. -> Option D
Quick Check:
Combinational logic = blocking assignments [OK]
Hint: Use blocking (=) for combinational, non-blocking (<=) for sequential [OK]
Common Mistakes:
Using non-blocking assignments in combinational blocks
2. Which of the following is the correct sensitivity list for a combinational always block in Verilog?
easy
A. always @(*)
B. always @(negedge reset)
C. always @(posedge clk)
D. always @(clk or reset)
Solution
Step 1: Identify combinational block sensitivity
Combinational logic should react to all input changes, so always @(*) automatically includes all signals read inside the block.
Step 2: Compare other options
Options with clock edges or specific signals are used for sequential logic, not combinational.
Final Answer:
always @(*) -> Option A
Quick Check:
Combinational sensitivity = always @(*) [OK]
Hint: Use always @(*) for combinational blocks to cover all inputs [OK]
Common Mistakes:
Using clock edges in combinational blocks
Listing incomplete sensitivity signals manually
Forgetting to include all inputs causing latches
3. What is the output of the following Verilog code snippet when clk rises?
reg q;
always @(posedge clk) begin
q = d;
end
medium
A. q updates but may cause simulation vs synthesis mismatch
B. Syntax error due to blocking assignment in sequential block
C. q updates correctly on clock edge
D. q never updates
Solution
Step 1: Analyze assignment type in sequential block
The code uses blocking assignment (=) inside a clocked always block, which is not recommended for registers.
Step 2: Understand synthesis vs simulation behavior
While synthesis tools may infer the register correctly, simulation can show unexpected behavior due to immediate assignment instead of scheduled update.
Final Answer:
q updates but may cause simulation vs synthesis mismatch -> Option A
Hint: Use non-blocking (<=) in sequential blocks to avoid mismatches [OK]
Common Mistakes:
Using blocking (=) in clocked always blocks
Expecting immediate update in sequential logic
Confusing simulation behavior with synthesis
4. Identify the error in the following Verilog code snippet intended for synthesis:
always @(posedge clk) begin
if (enable)
q <= d;
else
; // missing else assignment
end
medium
A. Sensitivity list is incomplete
B. Using non-blocking assignment in sequential block is wrong
C. Missing non-blocking assignment in else branch causes inferred latch
D. Syntax error due to empty else statement
Solution
Step 1: Check assignments in all branches
The else branch has no assignment to q, so q retains its previous value, causing a latch to be inferred.
Step 2: Understand synthesis best practice
To avoid latches, all outputs must be assigned in every branch of a sequential block.
Final Answer:
Missing non-blocking assignment in else branch causes inferred latch -> Option C
Quick Check:
All branches assign outputs to avoid latches [OK]
Hint: Assign outputs in all if-else branches to prevent latches [OK]
Common Mistakes:
Leaving else branch empty causing inferred latch
Confusing blocking and non-blocking assignments
Ignoring sensitivity list completeness in sequential blocks
5. You want to design a 4-bit counter with synchronous reset using best synthesis practices. Which code snippet correctly implements this?
hard
A. always @(posedge clk or posedge reset) begin
if (reset)
count <= 0;
else
count = count + 1;
end
B. always @(posedge clk) begin
if (reset)
count <= 0;
else
count <= count + 1;
end
C. always @(posedge clk) begin
if (reset == 1'b1)
count = 0;
else
count <= count + 1;
end
D. always @(posedge clk) begin
if (reset)
count <= 0;
else
count = count + 1;
end
Solution
Step 1: Identify synchronous reset and non-blocking assignments
Synchronous reset means reset is checked only on clock edge, so sensitivity list should only have posedge clk. Non-blocking assignments (<=) must be used for registers.
Step 2: Evaluate each option
always @(posedge clk or posedge reset) begin
if (reset)
count <= 0;
else
count = count + 1;
end uses asynchronous reset (posedge reset) and blocking assignment in else branch, which is not best practice. always @(posedge clk) begin
if (reset == 1'b1)
count = 0;
else
count <= count + 1;
end mixes blocking and non-blocking assignments. always @(posedge clk) begin
if (reset)
count <= 0;
else
count = count + 1;
end uses blocking assignment in else branch. Only always @(posedge clk) begin
if (reset)
count <= 0;
else
count <= count + 1;
end uses synchronous reset and non-blocking assignments consistently.
Final Answer:
Option B correctly implements a 4-bit counter with synchronous reset and proper assignments. -> Option B
Quick Check:
Synchronous reset + non-blocking assignments = always @(posedge clk) begin
if (reset)
count <= 0;
else
count <= count + 1;
end [OK]
Hint: Use only posedge clk and non-blocking (<=) for synchronous reset counters [OK]
Common Mistakes:
Mixing blocking and non-blocking assignments in sequential logic
Using asynchronous reset when synchronous is required
Including reset in sensitivity list for synchronous reset
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.