Streaming CRC-8

Hard · Arithmetic · Sequential Logic

Implement a CRC-8 engine that processes a stream of bytes, one byte per clock cycle.

A cyclic redundancy check (CRC) is the remainder of a polynomial division over GF(2). It is used on almost every link (Ethernet, USB, SMBus, CAN) to detect corrupted data. This problem uses the CRC-8/SMBUS variant:

ParameterValue
Width8 bits
Polynomialx⁸ + x² + x + 1, written 8'h07 (the x⁸ term is implicit)
Initial value8'h00
Bit orderMSB first, no reflection of input or output
Final XORnone (8'h00)
Check valuethe ASCII string "123456789" gives 8'hF4

Processing one byte

Given the current CRC c and an input byte d, the next CRC is computed by:

c = c ^ d
repeat 8 times:
    if c[7] == 1:  c = (c << 1) ^ 8'h07     // keep 8 bits
    else:          c = (c << 1)

(Bit 7 is examined before the shift, and the result is truncated to 8 bits.)

Ports

PortDirWidthMeaning
clkinput1Clock; everything happens on the rising edge.
rstinput1Synchronous, active-high reset: it acts only at a rising edge (a pulse between edges has no effect).
clearinput1Start a new message (synchronous).
validinput1data holds a byte to absorb this cycle.
datainput8Input byte. Ignored when valid = 0.
crcoutput8Current CRC register.

Behavior on each rising edge (in priority order)

  1. rst = 1: crc ← 8'h00.
  2. else clear = 1 and valid = 0: crc ← 8'h00 (the initial value).
  3. else clear = 1 and valid = 1: the byte is the first byte of a new message:

crc ← next(8'h00, data).

  1. else valid = 1: crc ← next(crc, data).
  2. else: crc holds its value.

crc is a register: it changes only at rising edges. A byte presented with valid = 1 in cycle n is reflected in crc from cycle n + 1 on. Bytes may arrive back to back (valid high on consecutive cycles), and there may be any number of idle cycles (valid = 0, "bubbles") between bytes; data may hold garbage during bubbles.

Timing diagram

Reset, then "12" back to back, a bubble, "3", an idle cycle, and a new message AB CD whose first byte arrives together with clear:

Examples

Bytes (from 8'h00, after clear or reset)Resulting crc
8'h008'h00
8'h018'h07
8'h808'h89
8'hFF8'hF3
"1" = 8'h318'h97
"12" = 8'h31 8'h328'h72
"123456789"8'hF4
8'hAB 8'hCD8'hE2

Hints

input logic [7:0] d); and call it from always_ff`. The loop unrolls into a small XOR network: the whole byte is processed in one clock cycle.

polynomial 8'hE0); those give different results here.

Sign up free to solve Streaming CRC-8 in your browser.

More Arithmetic problems