SystemVerilog gives you two assignment operators. The blocking form, =, executes immediately, one statement after another in order. The nonblocking form, <=, schedules an update to take effect at the end of the time step or clock cycle. They look almost identical in code but they behave completely differently, and in a design with multiple registers they can create timing bugs that pass simulation but fail in silicon. The lesson is not about which one is faster or smarter: it is about which one matches how hardware actually works.
Blocking assignment is the right choice for combinational logic, where you compute a value from inputs in the present moment and feed it forward instantly. Nonblocking is the rule inside clocked always blocks, where you are modeling how real registers behave: at a clock edge, every register samples its input, then all of them update together. Nonblocking assignment ensures that a value from one register does not race into the next register in the same cycle, a bug that simulation hides but silicon exposes.
If you use blocking assignment inside a clocked block, a value can propagate through multiple pipeline stages in a single cycle. In a two-stage pipeline with blocking assignment in the first stage, data from the input reaches the second stage output immediately, not one cycle later. Your simulation passes and your hardware fails because the silicon clock is slower. Lint tools flag this automatically, just as they flag accidental latches in combinational logic, because the rule is: this is how you avoid a silent, expensive bug.
The choice between blocking and nonblocking is not a style preference, it is the difference between correct and incorrect hardware. The code might compile and simulate either way, but only one is right. That is why the engine on this page enforces it the same way a professional lint flow does on the job. Use blocking inside a clocked block and it will be flagged, the same habit from Page 10, where the blocking rule kept you from race hazards across a single cycle. Here the stakes are timing: the whole design depends on every stage updating in lock step. Nonblocking assignment guarantees that.
Write a two-stage pipeline where each stage has a register. On each rising clock edge, the first stage samples the input, then the second stage samples the first stage. Use nonblocking assignment in both stages. If you use blocking assignment, the engine will detect it, and you will see exactly how a value races through the pipeline in a single cycle instead of waiting for the next edge. Run and submit. The engine is a cycle-accurate pipeline simulator.
Weekly intelligence on VLSI, AI for EDA, and chip careers. 20,000+ engineers already inside.