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:
| Parameter | Value |
|---|---|
| Width | 8 bits |
| Polynomial | x⁸ + x² + x + 1, written 8'h07 (the x⁸ term is implicit) |
| Initial value | 8'h00 |
| Bit order | MSB first, no reflection of input or output |
| Final XOR | none (8'h00) |
| Check value | the ASCII string "123456789" gives 8'hF4 |
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.)
| Port | Dir | Width | Meaning |
|---|---|---|---|
clk | input | 1 | Clock; everything happens on the rising edge. |
rst | input | 1 | Synchronous, active-high reset: it acts only at a rising edge (a pulse between edges has no effect). |
clear | input | 1 | Start a new message (synchronous). |
valid | input | 1 | data holds a byte to absorb this cycle. |
data | input | 8 | Input byte. Ignored when valid = 0. |
crc | output | 8 | Current CRC register. |
rst = 1: crc ← 8'h00.clear = 1 and valid = 0: crc ← 8'h00 (the initial value).clear = 1 and valid = 1: the byte is the first byte of a new message:crc ← next(8'h00, data).
valid = 1: crc ← next(crc, data).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.
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:
Bytes (from 8'h00, after clear or reset) | Resulting crc |
|---|---|
8'h00 | 8'h00 |
8'h01 | 8'h07 |
8'h80 | 8'h89 |
8'hFF | 8'hF3 |
"1" = 8'h31 | 8'h97 |
"12" = 8'h31 8'h32 | 8'h72 |
"123456789" | 8'hF4 |
8'hAB 8'hCD | 8'hE2 |
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.