← All problems

I2C Master Controller

Hard · Sequential · SystemVerilog

Design a single-byte I2C master controller that generates START and STOP conditions, clocks an address byte and a data byte over the open-drain {scl_o}/{sda_o} bus, and handles ACK sampling and clock stretching.

## Open-Drain Bus Model

{scl_o} $= 0$ pulls the SCL line low; {scl_o} $= 1$ releases it (an external pull-up drives the line high when no device holds it low). The same convention applies to {sda_o}. The inputs {scl_i} and {sda_i} reflect the actual line levels. In the idle state both {scl_o} and {sda_o} are $1$ (released).

## Clock Generation

The SCL half-period is CLK_DIV {clk} cycles (parameter, default 4). SCL idles high. One SCL period consists of CLK_DIV cycles with {scl_o} $= 0$ followed by CLK_DIV cycles with {scl_o} $= 1$, giving an SCL frequency of $\text{clk frequency} \div (2 \times \text{CLK\_DIV})$.

## Clock Stretching

Open this challenge in the editor →