
HDL Models of Registers and Counters
How registers, shift registers, and counters are written in HDL for synthesis.
Description
Synthesizable RTL for clocked registers, shifters, and counters. RTL is how these sequential blocks are actually built in FPGAs/ASICs. Clocked always/process blocks with non-blocking assignment and a reset.
- Use always @(posedge clk) with non-blocking (<=) assignments.
- Include a reset (sync or async) to define the start state.
- Shift = q <= {serial_in, q[n-1:1]}; count = q <= q + 1.
- What: Synthesizable RTL for clocked registers, shifters, and counters.
- Why: RTL is how these sequential blocks are actually built in FPGAs/ASICs.
- How: Clocked always/process blocks with non-blocking assignment and a reset.
- Where: Every sequential block in a real design.
- When: From the first RTL through synthesis.
- Analogy — Writing sequential RTL is like giving instructions that only run on each tick of a metronome (the clock edge) — and you always say where to start (reset).
At a glance
What
Synthesizable RTL for clocked registers, shifters, and counters.
Why
RTL is how these sequential blocks are actually built in FPGAs/ASICs.
How
Clocked always/process blocks with non-blocking assignment and a reset.
Where
Every sequential block in a real design.
When
From the first RTL through synthesis.
Think of it like…
Writing sequential RTL is like giving instructions that only run on each tick of a metronome (the clock edge) — and you always say where to start (reset).
RTL rules for sequential logic
- Use always @(posedge clk) with non-blocking (<=) assignments.
- Include a reset (sync or async) to define the start state.
- Shift = q <= {serial_in, q[n-1:1]}; count = q <= q + 1.
Pattern → code
| Block | Core line |
|---|---|
| Register | q <= d; |
| Shift right | q <= {sin, q[N-1:1]}; |
| Up counter | q <= q + 1'b1; |
| Mod-N | if (q==N-1) q<=0; else q<=q+1; |
Black-box view
Inputs on the left → outputs on the right · particles show signal direction
The counter this RTL describes
▶ live simulatorPress Step or Runto count; each bit's waveform is traced live.
HDL — Verilog · VHDL · SystemVerilog
module counter #(parameter N = 4)
(input clk, rst, en, output reg [N-1:0] q);
always @(posedge clk)
if (rst) q <= 0;
else if (en) q <= q + 1'b1;
endmoduleParameterized up-counter with synchronous reset and enable.
Real-world applications
The 5 Whys
- 1
Why non-blocking (<=)? It models parallel flip-flop updates correctly.
- 2
Why a reset? To define a known starting state.
- 3
Why posedge clk? To make the logic synchronous and synthesizable.
- 4
Why parameterize width? One module serves many bit-widths.
- 5
Root cause: a clocked block with non-blocking assignment maps directly to flip-flops.
Cheat sheet
Working principle
- Clocked always/process blocks with non-blocking assignment and a reset.
- Synthesizable RTL for clocked registers, shifters, and counters.
Formulas & Boolean expressions
- Use always @(posedge clk) with non-blocking (<=) assignments.
- Shift = q <= {serial_in, q[n-1:1]}; count = q <= q + 1.
- Register = q <= d;
- Shift right = q <= {sin, q[N-1:1]};
- Up counter = q <= q + 1'b1;
- Mod-N = if (q==N-1) q<=0; else q<=q+1;
Key facts
- Use always @(posedge clk) with non-blocking (<=) assignments.
Why it exists
- Root cause: a clocked block with non-blocking assignment maps directly to flip-flops.