
Tiny Canvas is a hardware implementation of an MS Paint-style drawing application. It receives input from an SNES-compatible gamepad controller via the Gamepad PMOD and streams canvas coordinates and color data over I2C to a host device.
Color Mixing: The A, Y, and X buttons toggle Red, Green, and Blue color channels respectively. These combine additively to produce 8 colors:
Brush Controls:
Fill Rectangle: Select button toggles fill mode. Press B to set corner A, move cursor, press B again to set corner B and fill the rectangle.
Undo/Redo: L+R together undoes, Select+Start together redoes (4-operation buffer).
The design consists of modular Verilog components:
gamepad_pmod_single: Decodes SNES controller serial protocolcolour: RGB mixing logic with smart paint-enableposition: 8-bit X/Y cursor trackingbrush_settings: Size (0-7) and symmetry mode (0-3) controlpacket_generator: Expands single pixels to brush footprint with symmetryfill_mode / fill_draw: Fill rectangle state machine and pixel generatorundo_redo: 4-entry circular buffer for undo/redo operationsi2c_slave: Read-only I2C slave at address 0x64Reading 3 bytes from address 0x64 returns:
| Byte | Content |
|---|---|
| 0 | X position (0-255) |
| 1 | Y position (0-255) |
| 2 | Status: [7:4]=D-pad, [3]=BrushMode, [2:0]=RGB |
pip install pygame cocotbpython test/interactive_emulator.pyui[0:2] (data, clock, latch)uio[1], SCL to uio[2]0x64 to read canvas statecd test
make
Required:
For canvas display:
The I2C interface streams X, Y, and color data at each paint event, allowing a host device to render the 256×256 canvas in real-time.
| # | Input | Output | Bidirectional |
|---|---|---|---|
| 0 | i2c_state[0] | ||
| 1 | i2c_state[1] | SDA | |
| 2 | i2c_state[2] | SCL | |
| 3 | |||
| 4 | pmod_latch | ||
| 5 | pmod_clk | ||
| 6 | pmod_data | ||
| 7 |