neorv32/docs/datasheet/soc_crc.adoc

72 lines
2.6 KiB
Plaintext

<<<
:sectnums:
==== Cyclic Redundancy Check (CRC)
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_crc.vhd |
| Software driver file(s): | neorv32_crc.c |
| | neorv32_crc.h |
| Top entity port: | none |
| Configuration generics: | `IO_CRC_EN` | implement CRC module when `true`
| CPU interrupts: | none |
|=======================
**Overview**
The cyclic redundancy check unit provides a programmable checksum computation module. The unit operates on
single bytes and can either compute CRC8, CRC16 or CRC32 checksums based on an arbitrary polynomial and
start value.
.DMA Demo Program
[TIP]
A CRC example program (also using CPU-independent DMA transfers) can be found in `sw/example/crc_dma`.
.CPU-Independent Operation
[TIP]
The CRC unit can compute a checksum for an arbitrary memory array without any CPU overhead
by using the processor's <<_direct_memory_access_controller_dma>>.
**Theory of Operation**
The module provides four interface registers:
* `MODE`: selects either CRC8-, CRC16- or CRC32-mode
* `POLY`: programmable polynomial
* `DATA`: data input register (single bytes only)
* `SREG`: the CRC shift register; this register is used to define the start value and to obtain
the final processing result
The `MODE`, `POLY` and `SREG` registers need to be programmed before the actual processing can be started.
Writing a byte to `DATA` will update the current checksum in `SREG`.
.Access Latency
[NOTE]
Write access to the CRC module have an increased latency of 8 clock cycles. This additional latency
ensures that the internal bit-serial processing of the current data byte has also been completed when the
transfer is completed.
.Data Size
[NOTE]
For CRC8-mode only bits `7:0` of `POLY` and `SREG` are relevant; for CRC16-mode only bits `15:0` are used
and for CRC32-mode the entire 32-bit of `POLY` and `SREG` are used.
**Register Map**
.CRC Register Map (`struct NEORV32_CRC`)
[cols="<2,<1,<4,^1,<7"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.2+<| `0xffffee00` .2+<| `CTRL` <|`1:0` ^| r/w <| CRC mode select (`00` CRC8, `01`: CRC16, `10`: CRC32)
<|`31:2` ^| r/- <| _reserved_, read as zero
| `0xffffee04` | `POLY` |`31:0` | r/w | CRC polynomial
.2+<| `0xffffee08` .2+<| `DATA` <|`7:0` ^| r/w <| data input (single byte)
<|`31:8` ^| r/- <| _reserved_, read as zero, writes are ignored
| `0xffffee0c` | `SREG` |`32:0` | r/w | current CRC shift register value (set start value on write)
|=======================