Registers, Counters & LFSRs

A counter with enable and load, terminal count, wrap-around — and a linear-feedback shift register that generates pseudo-random numbers.

Counters are everywhere in hardware: timers, baud-rate generators, PWM, address generators. A counter is a register plus an adder that feeds it back. Adding control inputs (reset, enable, load) is just priority logic in front of the register.

A loadable counter

{W{1'b0}} is W zero bits, so the reset value always matches the width.

count + 1'b1 increments; at 15 it wraps to 0 because the result is 4 bits.

assign tc = &count; is 1 only when every bit is 1 (the terminal count).

Pseudo-random numbers with an LFSR

count <= count + 1; // 32-bit literal count <= count + 1'b1;

Works in simulation, but the unsized 1 is 32 bits wide, so lint tools report a width mismatch. Sized constants keep widths explicit.

always @(posedge clk) if (count == 9) count <= 0; always @(posedge clk) count <= count + 1;

always @(posedge clk) if (count == 4'd9) count <= 4'd0; else count <= count + 1'b1;

One register, one always block. Two blocks driving count are multiple drivers.

How would you make a counter that counts 0 to 9 and repeats (a decade counter)?

Compare before incrementing: if (count == 4'd9) count <= 4'd0; else count <= count + 1'b1;

Why can an LFSR never be seeded with all zeros?

The feedback is an XOR of state bits; with all bits zero the feedback is zero, so the register stays at zero forever (a lock-up state).

A 4-bit counter is at 4'b1111 and en is high. What is it after the next rising edge, and what is tc before and after?

It wraps to 0000. tc = &count is 1 while count is 1111 and 0 after it wraps.