I2C Start and Stop Detector
Every I2C peripheral requires a mechanism to identify the beginning and end of a transaction on the bus. Unlike standard synchronous protocols where data changes only on clock edges, I2C uses data line (sda) transitions while the clock line (scl) is stable and high to signal Start and Stop conditions.
The module continuously samples the scl and sda inputs using a high-frequency system clock (clk). It must output a single-cycle high pulse on start_det when sda transitions from high to low while scl is high. Conversely, it must output a single-cycle high pulse on stop_det when sda transitions from low to high while scl is high. All sda transitions that occur while scl is low represent normal data transfer and must be ignored.
Positive-edge triggered clock clk. Asynchronous active-low reset rst_n. On reset, both start_det and stop_det are 0. The internal register tracking the previous state of sda must reset to 1 (the I2C idle state) to prevent false Stop condition detections when the module comes out of reset.
Worked Trace: • Cycle 1: rst_n=0 → start_det=0, stop_det=0 • Cycle 2: rst_n=1, scl=1, sda=1 → start_det=0, stop_det=0 • Cycle 3: rst_n=1, scl=1, sda=0 → start_det=1, stop_det=0 (SDA fell while SCL high) • Cycle 4: rst_n=1, scl=0, sda=0 → start_det=0, stop_det=0 (Start pulse is 1 cycle) • Cycle 5: rst_n=1, scl=0, sda=1 → start_det=0, stop_det=0 (Data change ignored) • Cycle 6: rst_n=1, scl=1, sda=1 → start_det=0, stop_det=0 • Cycle 7: rst_n=1, scl=1, sda=0 → start_det=1, stop_det=0 (Repeated start) • Cycle 8: rst_n=1, scl=1, sda=1 → start_det=0, stop_det=1 (Stop condition)
{ "signal": [
{ "name": "clk", "wave": "p......." },
{ "name": "rst_n", "wave": "01......" },
{ "name": "scl", "wave": "1..0.1.." },
{ "name": "sda", "wave": "1.0.1.01" },
{},
{ "name": "start_det", "wave": "0.10..10" },
{ "name": "stop_det", "wave": "0......1" }
], "head": { "text": "Start and Stop conditions are detected when SDA transitions while SCL is high." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered system clock | | rst_n | input | 1 | Asynchronous active-low reset; outputs go to 0 | | scl | input | 1 | I2C clock line | | sda | input | 1 | I2C data line | | start_det | output | 1 | Pulses high for 1 clk cycle upon Start detection | | stop_det | output | 1 | Pulses high for 1 clk cycle upon Stop detection |
Constraints
- The
start_detandstop_detoutputs must be exactly 1 clock cycle wide. - Internal registers tracking the previous state of the
sdaline must reset to 1. - Both outputs must be registered and updated on the positive edge of
clk. - Transitions on
sdamust be ignored ifsclis 0.
Topics
Solve this problem
Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.
This problem is part of Codiode Pro. The statement above is free to read.
The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.