ALearning Material
HDLs (Hardware Description Languages): Verilog and VHDL. Describe digital hardware, not software. This is the hardest mental shift: your code doesn't run line-by-line on a processor; it describes circuits that all exist and operate simultaneously. A "program" becomes gates and wires on an FPGA or chip.
The single hardest adjustment in HDL is realising your code does not run, it describes. In software, statements execute one after another on a processor; in Verilog or VHDL, statements describe physical hardware that all exists and operates at once. Ten lines aren't ten steps; they're ten pieces of circuitry running simultaneously, and missing this leads to fundamentally wrong designs.
Combinational logic (output depending only on the current inputs, with no memory) is where this
concurrency is clearest. A continuous assignment like assign y = a & b isn't executed once; it
creates a permanent wire-level relationship, so y is always equal to a AND b, updating the instant
either input changes, like a law of physics for that wire. Multiplexers and multi-bit buses build
on the same idea. Hold onto 'concurrent hardware, not sequential steps' and the rest of HDL falls
into place.
The golden rule: HDL is concurrent, not sequential. Ten statements describe ten pieces of hardware running at once, not ten steps in order.
Combinational logic = output depends only on the current inputs (no memory). It maps directly to gates (AND, OR, NOT, XOR). Example, a 2-input AND in Verilog:
module and_gate(input a, input b, output y);
assign y = a & b; // y is permanently wired = a AND b
endmodule
assign creates a continuous assignment. A permanent wire-level relationship.
Whenever a or b changes, y updates instantly (in reality, after a tiny gate
delay). It's not "executed once"; it's always true, like a law of physics for that
wire.
A multiplexer (mux): selects one of two inputs:
module mux2(input a, input b, input sel, output y);
assign y = sel ? b : a; // sel=1 -> y=b, sel=0 -> y=a
endmodule
Buses (multi-bit signals) use [n-1:0]:
module adder4(input [3:0] a, input [3:0] b, output [4:0] sum);
assign sum = a + b; // 4-bit + 4-bit -> 5-bit (carry out)
endmodule
Module = a reusable hardware block with named ports (inputs/outputs). You build big designs by instantiating smaller modules, like wiring chips together, not calling functions.
Why it exists. Processors run software one step at a time; for the fastest, most parallel, lowest-power circuits you describe the hardware itself. An HDL like Verilog specifies gates and wires that all exist and act at once. The foundation of FPGAs and chips, and a genuine mental shift from programming.
Mental model. Writing software is writing a to-do list executed top to bottom. Writing HDL is drawing a wiring diagram. Every component you draw exists and acts at the same time, the instant you power it on. Forgetting this ("it'll run in order") is the #1 beginner error.
Common misunderstandings.
- "HDL runs line by line like software." It is concurrent. Ten statements describe ten pieces of hardware operating at once, not ten ordered steps.
- "
assignexecutes once." A continuous assignment is a permanent wire-level relationship. Always true, updating whenever an input changes. - "Instantiating a module is calling a function." It places a physical copy of that hardware block and wires its ports, like soldering in another chip, not invoking code.
Connections. Concurrency, modules, and combinational logic are the base for sequential logic and FSMs (the next lesson and the traffic-light project), and for pipelining and timing in Turn 2. The same gates are what VLSI implements in CMOS transistors, and an FPGA built from this is the soft-core CPU capstone.
BImmediate Active Recall
QUERYWhat is the fundamental difference between HDL code and software code?
REVEAL
HDL describes hardware that operates concurrently (all statements are simultaneous circuits), not a sequence of instructions executed in order by a processor.
QUERYWhat does assign y = a & b; create, and when does y update?
REVEAL
assign y = a & b; create, and when does y update?A continuous assignment. A permanent gate/wire making y always equal a AND b; y updates whenever a or b changes (after a tiny gate delay).
QUERYWhat is combinational logic?
REVEAL
Logic whose outputs depend only on the present inputs, with no memory/state. It maps directly to gates.
QUERYWhat is a module, and how do you build large designs from modules?
REVEAL
A module is a reusable hardware block with input/output ports; you build big designs by instantiating (wiring together) smaller modules, like connecting chips.
CConceptual Questions
Answer each in your own words in the box, then reveal the model answer to compare. These ask why, not how, and your answers are saved.
Why is 'HDL is concurrent, not sequential' the hardest mental shift coming from software?
REVEAL MODEL ANSWER
Because HDL statements describe physical hardware that all exists and operates at the same time, not instructions executed in order. Ten assign statements are ten separate pieces of wiring, all live at once and all reacting to input changes simultaneously. If you read them as sequential lines of a program, 'first this, then that'. You build the wrong circuit, since there is no 'then' in concurrent hardware.
What does assign y = a & b; actually create, and how is it unlike a software assignment?
REVEAL MODEL ANSWER
It creates a continuous assignment. A permanent, wire-level relationship in which y is always equal to a AND b. It isn't executed once and finished; it holds true at all times, and y updates the instant a or b changes (after a tiny gate delay). A software assignment computes a value once at that point in the program's flow; this is a standing physical law for that wire.
In assign sum = a + b; with 4-bit a and b but a 5-bit sum, why is sum 5 bits wide?
REVEAL MODEL ANSWER
Adding two 4-bit numbers can overflow 4 bits, the maximum 15 + 15 = 30 needs 5 bits, so the extra bit captures the carry-out. Making sum 5 bits ensures the result isn't truncated; the top bit is the carry that a 4-bit result would lose.
DPractice Problems
P1 (easy). Write a continuous assignment for a 2-input XOR gate y = a ⊕ b.
P2 (medium). What does assign y = sel ? b : a; describe in hardware, and how
many inputs select the output?
P3 (harder). A beginner writes three assign statements and expects them to
execute "in order, so the last wins." Why is that wrong, and what actually happens if
two assigns drive the same output?
Solutionsclick to reveal
P1. assign y = a ^ b; (^ is XOR in Verilog).
P2. A 2-to-1 multiplexer: it routes input b to y when sel = 1, else a.
One select line chooses between two data inputs.
P3. HDL is concurrent. The three statements are three independent circuits
existing simultaneously, with no "order" or "last wins." If two assigns drive the
same wire, you've created a conflict (multiple drivers): in simulation the wire
goes to x (unknown), and in real hardware it's a short/contention. Each wire should
have exactly one driver.
EFeynman Exercise
Explain to a beginner why HDL is "a wiring diagram, not a recipe." Use the AND-gate
example: stress that y = a & b isn't a step that runs once, but a permanent
connection that's always true. Then explain why having two statements drive the same
wire is like connecting two outputs to one wire, a conflict.
REVEAL MODEL ANSWER
Writing HDL is like drawing the wiring of a circuit board, not writing a to-do list. On a to-do list
the steps happen in order; on a circuit board every wire and gate is live at the same instant,
constantly reacting to its inputs. assign y = a & b is just soldering y to the output of an AND
gate fed by a and b: it's not a thing that 'happens once', it's a connection that is simply true
forever, the way water always flows downhill wherever you lay the pipe.
FError Analysis Framework
- Sequential thinking. Why: software habits. Recognise: expecting "order" / "last line wins." Avoid: picture concurrent hardware; each statement = a circuit.
- Multiple drivers on a wire. Why: two assigns to one net. Recognise:
x/ contention. Avoid: one driver per signal. - Bus width mismatch. Why: assigning wrong-width signals. Recognise: truncation/ warnings. Avoid: size buses deliberately (mind carry bits).
- Forgetting gate delay reality. Why: assuming instant. Recognise: timing surprises later. Avoid: know outputs settle after propagation delay.
GMini Challenge
Write a 2-to-1 multiplexer in Verilog using a continuous assignment, and explain why all the 'statements' in a combinational module operate simultaneously rather than in sequence.
REVEAL MODEL ANSWER
module mux2(input a, input b, input sel, output y);
assign y = sel ? b : a; // sel=1 -> y=b, sel=0 -> y=a
endmodule
The assign is a permanent wire relationship, not a step that runs once. In a module with several
such assignments, each describes its own piece of physical gates and wires, and they are all live at
the same time, every one reacting to its inputs concurrently. There's no execution order because
it's real hardware operating in parallel, not lines of a program run in sequence.
Quiz Check
A quick auto-graded check, separate from the recall cards above. Your score is pooled with the recall cards into this module's Mastery score, and completing this lesson requires the quiz submitted with pooled mastery at 80% or above.