
This project implements a CRC-32 integrity verification engine (IEEE 802.3, polynomial 0xEDB88320) with an 8-byte internal FIFO and a real-time VGA display, designed for edge AI systems where data reliability is critical.
The design processes incoming data bytes through a serial CRC-32 engine that computes one bit per clock cycle (8 cycles per byte). This approach minimizes logic area while remaining fully functional within a single 1x1 Tiny Tapeout tile.
The internal blocks are:
8-byte circular FIFO: stores incoming data bytes written by the host via the bidirectional data bus. Implemented with 3-bit write/read pointers for natural modulo-8 wraparound. The host can write bytes while the CRC engine drains the FIFO concurrently.
Serial CRC-32 engine: processes one bit per clock cycle using the reflected polynomial 0xEDB88320 (standard IEEE 802.3, same as Ethernet). Each byte takes 8 cycles. The engine XORs the incoming byte with the low 8 bits of the CRC register, then shifts through all 8 bits applying the polynomial feedback on each step.
Control FSM: five-state machine (IDLE → LOAD → BITS → FINALIZE → DONE) that coordinates FIFO reads, bit-by-bit CRC updates, and result finalization. The CRC register is initialized to 0xFFFFFFFF and the final result is bit-inverted per the Ethernet standard.
Register interface: exposes internal state through a 4-bit address / 8-bit data bus:
address 0 returns status ({4'b0, irq, fifo_count[2:0]}), addresses 1–4 return the four CRC
result bytes (LSB first).
IRQ output: goes high when the CRC result is ready (crc_done) or when the FIFO is full,
enabling interrupt-driven operation.
VGA display (25 MHz, 640×480): provides a real-time visual readout of the engine state directly on a monitor via the TinyVGA PMOD:
fifo_count (each unit = 64 px).
Empty FIFO shows dark green background; occupied bytes light up bright green.enable (ui_in[6]) and writes data bytes into the FIFO by pulsing wr (ui_in[0]) while placing the byte on uio_in[7:0].irq goes high (visible on the VGA panel and readable via the register interface).wr pulse while in DONE state) resets crc_done and returns the FSM to IDLE.The testbench captures three VGA frames and compares them against reference images using CocoTB. On the first run, reference images are created automatically from the captured output.
cd test
make test
A passing result confirms the VGA timing, the register interface, and the CRC engine compile and simulate correctly. On subsequent runs, the test compares pixel-by-pixel against the saved references and fails if any difference is detected.
Required equipment:
uo_out — plug it in to see the live displayui_in and uioStep-by-step procedure:
uo_out and a VGA monitor. You should immediately see the
blue header and the status panel on screen.ui_in and uio per the pin table below.enable (ui_in[6] = 1). The BITS block on the VGA display turns cyan.uio_in[7:0]wr (ui_in[0] = 1 for one clock cycle)irq goes high (red block on VGA panel, or poll address 0 via the bus), the
result is ready.rd = 1 (ui_in[1] = 1) and cycle addr through 1, 2, 3, 4uio_out[7:0]import binascii
message = b"Hello"
expected = binascii.crc32(message) & 0xFFFFFFFF
print(f"Expected CRC-32: 0x{expected:08X}")
rst_crc (ui_in[7] = 1) for one cycle to reset the
engine and FIFO, then repeat from step 4.What you should see on the VGA monitor during a normal run:
| Phase | FIFO bar | FSM block color | CRC display |
|---|---|---|---|
| Idle, no data | Empty (dark green) | Grey | All dark blue |
| Writing bytes | Growing green bar | Grey (FIFO filling) | All dark blue |
| Processing | Shrinking bar | Yellow/Green cycling | Updating |
| Done | Empty | Blue | Final CRC bits |
| IRQ active | Empty | Blue | Final CRC bits, IRQ block = red |
uo_out.ui_in and the
bidirectional data bus uio.No additional hardware beyond the PMOD and a microcontroller is needed to use the full functionality of the module.
| Pin | Direction | Function |
|---|---|---|
ui_in[0] |
Input | wr — write strobe: pulse high to push uio_in byte into the FIFO |
ui_in[1] |
Input | rd — read strobe: pulse high to output register addr on uio_out |
ui_in[5:2] |
Input | addr[3:0] — register select: 0 = status, 1–4 = CRC result bytes (LSB first) |
ui_in[6] |
Input | enable — enables FIFO writes and CRC processing; must be high during operation |
ui_in[7] |
Input | rst_crc — soft reset: clears FIFO, CRC register, and FSM (synchronous) |
uo_out[7] |
Output | HSync — VGA horizontal sync (TinyVGA PMOD) |
uo_out[6] |
Output | B0 — VGA blue bit 0 (TinyVGA PMOD) |
uo_out[5] |
Output | G0 — VGA green bit 0 (TinyVGA PMOD) |
uo_out[4] |
Output | R0 — VGA red bit 0 (TinyVGA PMOD) |
uo_out[3] |
Output | VSync — VGA vertical sync (TinyVGA PMOD) |
uo_out[2] |
Output | B1 — VGA blue bit 1 (TinyVGA PMOD) |
uo_out[1] |
Output | G1 — VGA green bit 1 (TinyVGA PMOD) |
uo_out[0] |
Output | R1 — VGA red bit 1 (TinyVGA PMOD) |
uio[7:0] |
Bidir | data[7:0] — data bus: driven by host when writing, driven by chip when reading |
| Parameter | Value |
|---|---|
| CRC polynomial | 0xEDB88320 (IEEE 802.3 / Ethernet, reflected) |
| CRC width | 32 bits |
| Processing rate | 1 bit per cycle → 8 cycles per byte |
| Throughput at 25 MHz | ~3.125 Mbps (25 MHz / 8) |
| FIFO depth | 8 bytes |
| VGA resolution | 640 × 480 @ 25 MHz |
| Clock domain | Single (25 MHz) |
| Tile size | 1 × 1 |
This chip was designed with educational applications in mind. The following laboratories use the physical chip as the central learning artifact, progressing from basic understanding through offensive security and intelligent agent integration.
Prerequisites: Physical chip fabricated and mounted on a Tiny Tapeout demo board, TinyVGA PMOD, and a microcontroller (Arduino, RP2040, or ESP32).
Description: Students compute CRC-32 checksums of various messages in Python/C, then send the same data to the physical chip and compare results bit by bit.
Objective: Understand that CRC-32 is not just an abstract algorithm — it is real circuitry etched in silicon executing the same mathematics used by Ethernet, ZIP, and PNG.
What makes it interesting:
When the student sends "Hello" to the chip, the VGA monitor shows the CRC bits shifting in
real time as the engine runs. Watching hardware compute live is fundamentally different from
calling a Python function.
Knowledge gained: Solid foundation in data integrity, the difference between software and hardware implementations, and how the network link layer works internally.
Description: Students transmit messages to the chip and record the resulting CRC. They then alter specific bits of the message (1 bit, 2 bits, burst errors) and recalculate. They map which corruption patterns are detected and which slip through.
Objective: Understand the real limits of CRC-32 as an error-detection mechanism and why it is insufficient as a security control.
What makes it interesting: Students experimentally discover CRC collisions — two different messages that produce the same checksum. The chip confirms this physically, not just theoretically.
Knowledge gained: The critical difference between error detection (CRC) and tamper detection (HMAC, digital signatures). Foundation for understanding why checksums alone are not enough in cybersecurity contexts.
Description:
One student acts as the transmitter, another as an attacker using a logic analyzer to intercept
the uio bus. The attacker must modify the message in transit and recalculate a valid CRC so
the receiver detects no alteration.
Objective: Simulate a physical MitM attack where CRC provides no protection because the attacker can recompute it.
What makes it interesting: The attacker also has access to an identical chip — they use it to compute the CRC of the forged message before injecting it. Hardware attacking hardware.
Knowledge gained: Why modern protocols use secret keys in the integrity process (HMAC-SHA256). CRC has no secret — anyone can compute it. This naturally motivates the study of applied cryptography.
Description:
This is where the intelligent cybersecurity agent enters. A pipeline is built where the CRC chip
acts as a real-time integrity sensor for a stream of network packets. The agent receives
the irq signal and the resulting CRC from the chip, compares them against a database of known
signatures, and decides whether each packet is legitimate or anomalous.
Objective: Integrate physical hardware into the decision loop of a cybersecurity agent. The chip offloads integrity computation from the agent's CPU, freeing resources for reasoning.
What makes it interesting:
The agent does not compute the CRC — the chip does it in hardware at 3.125 Mbps. The agent
only consumes the result via irq and acts. This is a real hardware offloading architecture,
identical to how modern network interface cards (NICs) work.
Knowledge gained: Architecture of intrusion detection systems (IDS), hardware-assisted security, how intelligent agents can have physical sensors, and the design of hybrid security pipelines (hardware + AI).
Description: Files are stored with their CRC computed by the chip. Days later, students recompute the CRC using the same chip and detect whether files were modified. They then investigate who changed them and when.
Objective: Apply data integrity to a forensic context — verifying that digital evidence has not been altered since collection.
What makes it interesting: The chip produces a physical "seal" of the file. If the CRC does not match, the file was touched. Simple, tangible, and demonstrated visually on the VGA monitor in the classroom.
Knowledge gained: Digital chain of custody, hashing and integrity in forensics, and why legal institutions require integrity verification for electronic evidence. Also surfaces the limitations of CRC for this purpose (an attacker can recompute it), naturally leading to a discussion of cryptographic hashing with SHA-256.
The five laboratories form a deliberate pedagogical arc using the physical chip as the common thread throughout:
LAB 1 → Understand what the chip does
LAB 2 → Discover its limits
LAB 3 → Exploit it as an attacker
LAB 4 → Integrate it into an intelligent defense agent
LAB 5 → Apply it to real digital forensics
Students do not simulate — they work with real silicon at every step.
Jorge Luis Chuquimia Parra — GitHub: 27jorge05
Jorge Luis Chuquimia Parra GitHub: 27jorge05
| # | Input | Output | Bidirectional |
|---|---|---|---|
| 0 | wr | R1 | data[0] |
| 1 | rd | G1 | data[1] |
| 2 | addr[0] | B1 | data[2] |
| 3 | addr[1] | VSync | data[3] |
| 4 | addr[2] | R0 | data[4] |
| 5 | addr[3] | G0 | data[5] |
| 6 | enable | B0 | data[6] |
| 7 | rst_crc | HSync | data[7] |