3.5.3HDL & Digital Design Flow

Sequential logic and always blocks

2,076 words9 min readdifficulty · medium

WHY do we need sequential logic at all?


WHAT is an always block?


HOW: the two golden rules

There are two assignment operators and two block styles. Choosing correctly is 80% of avoiding bugs.

Blocking = vs non-blocking <= — derived from what hardware they mean


Figure — Sequential logic and always blocks

Deriving a D flip-flop from scratch


Combinational always (contrast, so you don't confuse them)




Recall Feynman: explain to a 12-year-old

Imagine a class where everyone writes an answer on a mini-whiteboard. A combinational kid shouts the answer the instant they see the question. A sequential kid only flips their board around when the teacher rings a bell (the clock) — until then they hold their last answer. Now, the tricky part: when the bell rings, all kids must show what they had written before the bell — not peek at their neighbour's new board. Non-blocking <= is the rule "read everyone's old board first, then flip together." Blocking = is "do it one by one," which is fine for the shout-instantly kids but chaos for the bell kids.


Active-recall

What triggers a sequential always block?
A clock edge, e.g. always @(posedge clk).
Which assignment for clocked/sequential logic?
Non-blocking <=.
Which assignment for combinational logic?
Blocking =.
Why does non-blocking <= model flip-flops correctly?
All RHS are evaluated using old values, then all LHS update simultaneously — matching parallel flops clocking together.
Why does blocking = break a shift register?
Later lines see the just-updated value, collapsing stages instead of shifting.
Is always @(posedge clk) a loop?
No — it is event-driven; it runs once per triggering edge then sleeps.
What is an inferred latch and when does it happen?
An unwanted memory element created when an always @(*) output isn't assigned in every branch.
How to avoid inferred latches?
Assign every output in every branch, or set defaults at the top of the block.
Difference between async and sync reset?
Async reset is in the sensitivity list and acts immediately; sync reset only acts on a clock edge.
Why put rst first in the if of a reset flop?
To give reset priority over normal data capture.
What does always @(*) mean?
Combinational logic sensitive to any signal read inside the block.
What error occurs if two always blocks drive the same reg?
Multiple-driver / race condition.

Connections

Concept Map

lacks

has

stored in

samples on

triggered by

models

models

use

use

reads old values then assigns

enables

Combinational logic

Sequential logic

Memory of past state

Flip-flop

Clock edge

always block

Sensitivity list

always @posedge clk

always @star

Non-blocking <=

Blocking =

Shift register

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, digital circuit do type ke hote hain. Combinational logic ki koi memory nahi hoti — jaise ek calculator jo turant answer de deta hai, output sirf current input pe depend karta hai. Sequential logic ke paas memory hoti hai — yeh apni "past state" yaad rakhta hai flip-flops mein. Aur sab flip-flops ek common clock ke edge pe hi apna value update karte hain, taaki poora chip sync mein rahe. Verilog mein hum isko always block se likhte hain.

Sabse important cheez yaad rakhni hai: always @(posedge clk) matlab sequential logic, aur yahan hamesha non-blocking <= use karo. always @(*) matlab combinational logic, aur yahan blocking = use karo. Mantra: "clock ke saath <=, comb ke saath =." Ek common galti — log samajhte hain always ek loop hai jo baar-baar fast chalta hai. Galat! Yeh event-driven hai: jab clock ka edge aata hai, tabhi ek baar body chalti hai, phir so jaata hai.

Non-blocking <= kyun zaroori hai? Socho ek shift register — q1 -> q2 -> q3. <= mein saare right-hand side pehle purane values se read hote hain, phir sab ek saath update hote hain — bilkul real flip-flops jaisa. Agar = use karoge, toh ek line agli line ka naya value dekh legi aur shifting toot jaayegi. Isliye clocked block mein hamesha <=.

Ek aur trap: always @(*) block mein agar kisi branch mein output assign nahi kiya, toh synthesizer ek latch bana deta hai (galti se memory add ho jaati hai). Fix — har branch mein har output ko assign karo, ya top pe default de do. In do rules ko pakka kar lo, aur sequential logic ke 80% bugs khatam.

Go deeper — visual, from zero

Test yourself — HDL & Digital Design Flow

Connections