Silicon Instead of Code: Why Verilog Is Not Programming
You already know how to write code. You've written variables, for loops, arrays, and if/else conditions more times than you can count. When you read x = a + b, your brain automatically translates it to "the computer loads a, loads b, adds them, and stores the result in x." That mental model is drilled into every programmer — and it's exactly what you need to unlearn.
Verilog looks like a programming language. It has semicolons, parentheses, and keywords like module, input, and output. But the moment you write assign out = a & b, you are not writing a sequence of instructions. You are drawing a blueprint. You are telling the silicon: "solder a wire from pin A to the left side of this AND gate, solder a wire from pin B to the other side, and connect the gate's output to the pin called out."
In a regular program, lines execute one after another. In hardware, everything happens at the same time — always. Parallelism isn't an optimization trick you opt into; it's the fundamental law of the physical world. When you connect two gates, both of them are running simultaneously, every nanosecond, forever.
Let's look at a concrete example. Say you want to build a simple safe lock: two buttons (A and B), and an alarm that goes off only when A is pressed AND B is NOT pressed. In Python, you'd write:
if a and not b:
alarm()
In Verilog, you build a circuit:
module SafeLock(
input wire a,
input wire b,
output wire alarm
);
wire not_b;
not g1(not_b, b);
and g2(alarm, a, not_b);
endmodule
Let's walk through this piece by piece. The not gate takes b and inverts it — if b is 0, not_b becomes 1, and vice versa. The and gate watches both a and not_b. It only outputs 1 when both of its inputs are 1. The wire alarm connects directly to that AND gate's output. There is no CPU, no instruction pointer, no fetch-decode-execute cycle. The AND gate and the NOT gate are both running right now, at this very instant, checking their inputs and updating their outputs every picosecond.
The wire not_b is the crucial concept here. In software, you'd store the intermediate result not b in a variable — a named memory location that exists temporarily. In hardware, wire not_b is a physical copper trace on the silicon. It doesn't "store" anything; it's literally a piece of metal connecting the output of the NOT gate to one input of the AND gate. If you could zoom in with a microscope, you'd see it.
This is the core insight that separates hardware design from programming: you are not commanding a processor, you are creating one. Every module you write becomes a physical block of logic gates. Every wire becomes a real connection. Your "program" is a schematic that gets etched into silicon.
In the Turing Complete game, this shift in thinking is the gate to a whole new world. Level 30 ("Hello, Wire!") starts with the simplest possible task: build an XOR gate from basic AND, OR, and NOT primitives. When you write xor g1(out, a, b), you're not calling a function — you're composing gates into a circuit that computes XOR as a physical fact.
Verilog isn't a programming language. It's a description language for eternity: once the silicon is fabricated, your circuit runs forever, without a reset, without an operating system, without a scheduler. Every gate is always on. Every wire is always connected. You're not writing code that will run — you're describing hardware that already is.