Friday, November 7, 2025

thumbnail

Top Mistakes Beginners Make in Verilog

 ⚠️ 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

Clock Divider Design

Parameterized Modules in Verilog

Visit Our Training Institute in Hyderabad

Get Directions

Subscribe by Email

Follow Updates Articles from This Blog via Email

No Comments

About

Search This Blog

Powered by Blogger.

Blog Archive