⚠️ Top Mistakes Beginners Make in Verilog
๐งฉ 1. Confusing Blocking (=) and Non-blocking (<=) Assignments
Mistake:
always @(posedge clk) begin
a = b; // Blocking assignment (wrong here)
c = a;
end
This causes unexpected results because a updates immediately, affecting c in the same clock cycle.
Correct:
always @(posedge clk) begin
a <= b; // Non-blocking (for sequential logic)
c <= a;
end
Rule of thumb:
Use <= inside clocked (posedge or negedge) always blocks.
Use = inside combinational always blocks (always @(*)).
๐ 2. Forgetting Sensitivity Lists in Combinational Logic
Mistake:
always @(a) begin // Missing 'b'!
y = a & b;
end
If b changes, y won’t update.
Correct:
always @(*) begin
y = a & b;
end
Tip: Use @(*) (Verilog 2001 and later) for automatic sensitivity detection.
⚙️ 3. Mixing Combinational and Sequential Logic
Mistake:
Putting both in one always block:
always @(posedge clk or a or b)
if (reset)
y <= 0;
else
y = a & b; // Combines clocked and combinational logic
Correct:
Separate them:
always @(posedge clk)
if (reset)
y <= 0;
always @(*)
next_y = a & b;
๐พ 4. Not Initializing or Resetting Registers
Uninitialized registers can lead to unpredictable simulation results.
Mistake:
reg [3:0] counter;
always @(posedge clk)
counter <= counter + 1;
Correct:
reg [3:0] counter = 0; // or initialize in a reset block
๐ง 5. Assuming Simulation = Hardware
ModelSim (simulation) and synthesis tools (hardware) can behave differently.
Example:
Using delays (#10) works in simulation but is ignored during synthesis.
Mistake:
#5 clk = ~clk; // Only simulation delay, not synthesizable
Tip:
Use delays only in testbenches — never in synthesizable design code.
๐ข 6. Mismatched Bit Widths
Mistake:
reg [3:0] a;
reg [7:0] b;
assign b = a; // Works but upper bits are lost!
Tip:
Be explicit about width extension:
assign b = {4'b0000, a}; // Zero-extend
๐งพ 7. Forgetting Default Assignments in always @(*)
Without a default, signals might infer latches unintentionally.
Mistake:
always @(*) begin
if (sel)
y = a;
// Missing else → latch inferred
end
Correct:
always @(*) begin
y = 0; // Default value
if (sel)
y = a;
end
๐งฐ 8. Incorrect Port Connections
Mistake:
my_module u1 (a, b, c, d); // Positional ports – error-prone
Correct:
my_module u1 (
.clk(clk),
.reset(rst),
.data_in(a),
.data_out(b)
);
Tip: Always use named port mapping for clarity.
๐ 9. Not Using a Proper Testbench
Beginners often simulate only the design module, not a full testbench.
Fix:
Create a testbench that:
Instantiates the DUT (Design Under Test)
Applies stimulus (inputs)
Observes outputs using $monitor, $display, or waveform viewer
๐งฎ 10. Ignoring Time Units
Mistake:
#10; // But what is 10? ns? ps?
Correct:
`timescale 1ns/1ps
#10; // Now it means 10 ns
✅ Quick Summary Table
Type Common Mistake Correct Practice
Assignment Using = in sequential logic Use <=
Sensitivity Missing signals Use @(*)
Reset Not initializing Add reset logic
Width Bit mismatch Match or extend bits
Testbench Missing testbench Always test with one
Timing No timescale Use \timescale`
Learn VLSI Training in Hyderabad
Read More
Simulating Verilog Code using ModelSim
VHDL Basics: Syntax and Structure
Parameterized Modules in Verilog
Visit Our Training Institute in Hyderabad
Subscribe by Email
Follow Updates Articles from This Blog via Email
No Comments