The short answer: Verilog interviews test two things: whether you understand how the language simulates (blocking vs non-blocking, the scheduler, 4-state values, sensitivity lists) and whether you can write clean, synthesisable RTL on the spot (flip-flops, counters, edge detectors, FSMs, synchronisers). Expect at least one “write this module” question, and expect to explain why your code would or wouldn’t synthesise.
Verilog is the language almost every VLSI interview uses, even for verification and physical design roles. I’ve split this post into concept questions and coding questions, because interviewers usually do both: a few “what’s the difference between” questions, then “write it on the board”.
For design-level questions (FIFOs, pipelines, arbiters), see my RTL design interview questions. This post stays focused on the language itself.
- How Verilog simulates
- Language concepts
- Coding questions
- How I’d prepare
Table of Contents
Part 1: How Verilog simulates

1. What is the difference between blocking (=) and non-blocking (<=) assignments?
A blocking assignment updates the variable immediately, so the next statement sees the new value. A non-blocking assignment reads the right-hand side now but updates the left-hand side later, in the NBA region, after every always block triggered by the same edge has run. That’s why non-blocking models flip-flops correctly.
My rule: non-blocking in clocked blocks, blocking in combinational blocks, and never mix them on the same variable.
2. What do these two blocks synthesise to?
always @(posedge clk) begin // (a)
b = a;
c = b;
end
always @(posedge clk) begin // (b)
b <= a;
c <= b;
end
(a) gives c the new value of b, which is a, so c is effectively one flop fed by a (and b may be a second flop with the same input). (b) is a two-stage shift register: a → b → c.
3. How do you swap two registers without a temporary variable?
always @(posedge clk) begin
a <= b;
b <= a;
end
Both right-hand sides are read before either left-hand side updates, so the swap works. With blocking assignments it wouldn’t.
4. What is a race condition in Verilog?
When the result depends on the order the simulator runs blocks that trigger at the same time. Classic example: one always block writes a variable with a blocking assignment on posedge clk, and another reads it on the same edge. Different simulators (or even runs) can give different answers. Non-blocking assignments for sequential logic avoid it.
5. What is the difference between $display, $strobe, $monitor and $write?
$display prints immediately when executed (in the active region), so it can show old values of non-blocking assignments. $strobe prints at the end of the time step, after NBA updates. $monitor prints whenever any of its arguments change. $write is $display without the newline.
6. What is the difference between == and ===?
== is logical equality: if either operand has x or z bits the result can be x. === is case equality: it compares x and z literally and always returns 0 or 1. === is for testbenches; it doesn’t synthesise.
7. What are the four values in Verilog?
0, 1, x (unknown) and z (high impedance). An x in simulation usually means something was never reset, two drivers conflict, or a signal is undriven. Real hardware only has 0 and 1, so x-propagation can hide or create bugs between RTL and gate-level simulation.
Part 2: Language concepts
8. wire vs reg: what’s the difference?
A wire is driven continuously by an assign or a module output. A reg holds its value until it’s assigned again in a procedural block. Despite the name, reg doesn’t mean a register: a reg assigned in always @(*) is combinational logic. (SystemVerilog’s logic removes most of this confusion.)
9. When does synthesis infer a latch, and how do you avoid it?
When a combinational always block doesn’t assign an output in every path, for example an if without an else, or a case without a default. The tool must hold the old value, so it adds a latch. Fix it by assigning default values at the top of the block.
always @(*) begin
y = 1'b0; // default: no latch
if (en) y = d;
end
10. Why use always @(*) instead of listing signals?
If you forget a signal in a manual sensitivity list, simulation doesn’t update when it changes, but synthesis ignores the list and builds the real logic. That’s a simulation-synthesis mismatch. @(*) includes every signal read in the block.
11. What is the difference between case, casez and casex?
case compares all four values exactly. casez treats z (or ?) as don’t-care. casex treats both x and z as don’t-care, which can hide x bugs in simulation, so I avoid casex and use casez with ? for wildcards.
12. What is the difference between a task and a function?
A function returns one value, runs in zero time, and can’t contain delays or event controls. A task can have several outputs, can consume time (#, @, wait), and can call other tasks. Functions are synthesisable if their contents are; tasks with timing are testbench-only.
13. `define vs parameter vs localparam?
`define is a global text macro that leaks across files. parameter is a per-module constant that can be overridden at instantiation. localparam is a module constant that can’t be overridden, ideal for state encodings and derived widths.
14. What are generate blocks used for?
To create hardware conditionally or repeatedly at elaboration time: a for-generate with a genvar to instantiate N copies of a module, or an if-generate to choose an implementation from a parameter.
15. Which Verilog constructs aren’t synthesisable?
Delays (#10, ignored by synthesis), initial blocks for ASICs (FPGAs can use them for power-up values), system tasks like $display, fork-join, real numbers, === and !==, and most event-control tricks. Delays are the classic trap: the RTL simulates one way and the netlist behaves another.
16. How does Verilog handle signed arithmetic?
Declare signals as signed or use $signed(). Be careful: if any operand in an expression is unsigned, the whole expression is treated as unsigned. Mixing widths also matters, because operands are extended to the widest width before the operation.
17. Why use `default_nettype none?
By default, a misspelled signal name in a port connection silently creates a new 1-bit wire. `default_nettype none turns that into a compile error.
Part 3: Coding questions
18. Write a D flip-flop with asynchronous active-low reset.
always @(posedge clk or negedge rst_n)
if (!rst_n) q <= 1'b0;
else q <= d;
19. Write a rising-edge detector.
reg d_q;
always @(posedge clk or negedge rst_n)
if (!rst_n) d_q <= 1'b0;
else d_q <= d;
assign rise = d & ~d_q; // one-cycle pulse
Falling edge is ~d & d_q, and any edge is d ^ d_q.
20. Write a parameterised modulo-N counter.
module mod_counter #(parameter N = 10, W = $clog2(N)) (
input wire clk, rst_n, en,
output reg [W-1:0] count
);
always @(posedge clk or negedge rst_n)
if (!rst_n) count <= 0;
else if (en) count <= (count == N-1) ? 0 : count + 1'b1;
endmodule
21. Write a 4-bit maximal-length LFSR.
// x^4 + x^3 + 1, cycles through 15 non-zero states
always @(posedge clk or negedge rst_n)
if (!rst_n) lfsr <= 4'b0001; // must not be all zeros
else lfsr <= {lfsr[2:0], lfsr[3] ^ lfsr[2]};
22. Count the number of 1s in a vector.
integer i;
always @(*) begin
ones = 0;
for (i = 0; i < W; i = i + 1)
ones = ones + in[i];
end
The loop unrolls into an adder tree in synthesis. Make sure ones is wide enough: $clog2(W+1) bits.
23. How do you check if a number is a power of two?
assign is_pow2 = (x != 0) && ((x & (x - 1)) == 0);
24. Write a two-flop synchroniser.
reg s1, s2;
always @(posedge clk_dst or negedge rst_n)
if (!rst_n) {s2, s1} <= 2'b00;
else {s2, s1} <= {s1, async_in};
Only for single-bit signals. Multi-bit data needs a handshake or an async FIFO. See clock domain crossing.
25. How do you generate a clock in a testbench?
initial clk = 1'b0;
always #5 clk = ~clk; // 10 time-unit period
26. What is the output of this code?
initial begin
a = 0;
a <= 1;
$display("display: %0d", a);
$strobe ("strobe: %0d", a);
end
display: 0 and strobe: 1. $display runs before the non-blocking update; $strobe runs after it.
Part 4: How I’d prepare
- Write every snippet above from memory, then simulate it. Small mistakes, like a missing default, are exactly what interviewers look for.
- Be ready to draw the hardware your code creates. “What does this synthesise to?” is a very common follow-up.
- Know the blocking/non-blocking rules well enough to explain why, using the scheduling diagram.
- Practise reading other people’s code and spotting bugs; some interviews hand you broken RTL.
Practise this on VLSI Forge
I built VLSI Forge so you can write RTL in your browser, run it on a real simulator and check every signal in the waveform. Free, nothing to install.
FAQ
Is Verilog still asked if the company uses SystemVerilog?
Yes. SystemVerilog is a superset of Verilog, and the core questions (blocking vs non-blocking, latches, synthesis) are the same. See my SystemVerilog interview questions for the extras.
Do I need to write code on paper in the interview?
Often, yes, or in a shared editor without a simulator. Practise writing small modules without autocomplete.
How long should my answers be?
One or two sentences, then stop and let the interviewer follow up. Long answers waste time and invite tangents.
What is the most common Verilog mistake in interviews?
Mixing blocking and non-blocking assignments, and forgetting defaults in combinational blocks, which creates latches.
