Module 1310 min

Common RTL Building Blocks

The small circuits you reuse everywhere

A handful of small circuits show up again and again in real designs. Knowing them as patterns means you can build most datapaths and control logic quickly, and they are common interview asks.

Edge detector

Detect the moment a signal changes, by comparing it to its value one cycle ago.

verilog
// One-cycle pulse when d goes from 0 to 1
reg d_q;
always @(posedge clk) d_q <= d;
wire rising = d & ~d_q;   // falling edge: ~d & d_q

Shift register

verilog
// Serial-in shift register
always @(posedge clk)
  shreg <= {shreg[WIDTH-2:0], serial_in};

Priority arbiter

When several requesters compete, grant the highest-priority one. Here the lowest index wins.

verilog
always @(*) begin
  grant = 4'b0000;
  if      (req[0]) grant = 4'b0001;
  else if (req[1]) grant = 4'b0010;
  else if (req[2]) grant = 4'b0100;
  else if (req[3]) grant = 4'b1000;
end

Synchronous FIFO, in one idea

A single-clock FIFO is a small memory with a write pointer and a read pointer. Write advances one, read advances the other, full is when they are about to collide, and empty is when they are equal. (The two-clock version, with gray-coded pointers, is the asynchronous FIFO in the CDC path.)

BlockUsed for
Edge detectorTurn a level change into a one-cycle pulse
Shift registerSerialize, delay, or align data
ArbiterPick one winner among requesters
FIFOBuffer data between producer and consumer
Pro tip

interviewers love asking you to code one of these on the spot: an edge detector, a round-robin arbiter, a FIFO. Practice writing each from memory. They are small, they reveal whether you really think in hardware, and they come up constantly.

Watch out

a simple priority arbiter always favours the same requester, so a low-priority one can starve. If fairness matters, use a round-robin arbiter that rotates which requester has top priority each grant.