
Finished implementing UART, SPI and I²C from scratch in Verilog
Over the past month, I've been learning serial communication protocols by implementing them in Verilog.
I started with UART, then moved to SPI, and finally finished I²C. I've now put all three into a single repository.
Some of the main features:
- UART: TX/RX, 16× oversampling, parity and error detection
- SPI: Master/Slave, all four CPOL/CPHA modes, full-duplex communication
- I²C: Master/Slave, 7-bit addressing, ACK/NACK, READ/WRITE and multi-byte transfers
- Parameterized RTL and self-checking verification across the designs.
One thing I found interesting was how different the implementation difficulty was despite all three being serial protocols. UART was relatively straightforward once the sampling logic was sorted out, SPI introduced clock-edge/phase handling, while I²C was easily the most annoying one to debug because both devices share the same bus and SDA has to be released/driven at exactly the right points.
I'd really appreciate feedback on the implementations, verification approach, or anything you'd change to make these closer to practical, reusable communication IP.
(I know many will suggest it is high time to start using SystemVerilog... I promise it's the next thing i am learning lmao)
GitHub: https://github.com/theYash856/Communication_Protocols
Could've posted this earlier, but GitHub decided to go down precisely when I was about to upload the project 😭