Skip to content

adaptableCoder/I2C-SystemVerilog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

I2C Master Controller

This repository contains a synthesizable I2C Master module written in SystemVerilog. The module serves as a communication bridge between a host system (such as an FPGA or microcontroller) and external I2C peripherals.

The architecture generates the SCL clock continuously and uses synchronous edge-detectors (scl_fall and scl_rise) internally. This allows the state machine to shift and sample data in alignment with the physical I2C clock edges.

For details about the I2C protocol, please refer to the official specification: NXP_I2C_Manual.pdf (https://www.nxp.com/docs/en/user-guide/UM10204.pdf).

Features

  • Configurable Clock Rates: The main system clock frequency and the target I2C bus frequency are parameterizable.
  • Direct Interface: The module accepts standard I2C Read/Write bits (0 for Write, 1 for Read).
  • Error Handling: Asserts an ack_error flag if a target peripheral fails to acknowledge an address or data byte.
  • Zero-Latency Data Transfer: Solves 1-clock-cycle synchronous latency by pre-loading the SDA shift register prior to data phases.

Pinout and Interface

System Inputs

  • clk: Main system clock (Default: 50 MHz).
  • reset: Active-high synchronous reset.

Control and Data Interface

  • start: Active-high pulse to initiate an I2C transaction.
  • rw: Determines transaction type (0 = Write, 1 = Read).
  • slave_addr [6:0]: 7-bit address of the target I2C peripheral.
  • data_in [7:0]: Data to be transmitted to the peripheral (ignored during Read operations).
  • data_out [7:0]: Data received from the peripheral (valid when done is asserted).

Status Flags

  • busy: High while a transaction is actively occurring.
  • done: Pulses high when a transaction terminates.
  • ack_error: High if a Not Acknowledge (NACK) is detected.

Physical I2C Bus

  • sda (inout): Bidirectional serial data line.
  • scl (output): Serial clock line.

Instantiation Template

i2c_master #(
    .CLK_FREQ(50_000_000), // Main system clock frequency
    .I2C_FREQ(100_000)     // Target I2C bus frequency
) i2c_master_inst (
    .clk(clk),
    .reset(reset),
    .start(start),
    .rw(rw),
    .slave_addr(slave_addr),
    .data_in(data_in),
    .data_out(data_out),
    .busy(busy),
    .done(done),
    .ack_error(ack_error),
    .sda(sda),
    .scl(scl)
);

Usage Examples

Write Operation

To transmit 0xC3 to address 0x5A:

  1. Assign slave_addr = 7'h5A.
  2. Assign data_in = 8'hC3.
  3. Assign rw = 0.
  4. Pulse start high for one clk cycle.
  5. Wait for done to assert. If ack_error is 0, the transmission was successful.

Read Operation

To read one byte from address 0x5A:

  1. Assign slave_addr = 7'h5A.
  2. Assign rw = 1.
  3. Pulse start high for one clk cycle.
  4. Wait for done to assert.
  5. If ack_error is 0, the received data is available on data_out.

Architecture and State Machine

The module generates the scl clock by dividing the main clk and uses 1-cycle delayed signals (scl_prev) to create scl_fall and scl_rise trigger pulses. The state machine uses these triggers to ensure all SDA transitions happen on the falling edge of SCL, and sampling happens on the rising edge.

State Progression:

  1. IDLE: Waiting for the start assertion.
  2. START: Asserts the Start Condition.
  3. ADDRESS: Shifts out the 7-bit slave_addr followed by the rw bit.
  4. ACK1: Samples the peripheral's acknowledge bit. For a Write, it pre-loads the first data bit onto SDA on the exiting scl_fall.
  5. DATA: Sequentially transmits or receives 8 bits of data.
  6. ACK2: Samples the peripheral's data ACK (Write) or generates a Master NACK (Read) to terminate.
  7. STOP_LOW / STOP_HIGH: Stages the SDA line low, then releases it high while SCL is high to assert a Stop Condition.
  8. DONE: Asserts the done flag and prepares to return to IDLE.

Simulation

The project includes simulation scripts for quick testing. Running these scripts will:

  1. Compile the design and testbench (design.sv, tb.sv) using Icarus Verilog (iverilog).
  2. Execute the simulation and generate a waveform file (vvp).
  3. Automatically open the resulting .vcd waveform in GTKWave for visual inspection.

Requirements: Ensure Icarus Verilog and GTKWave are installed and added to your system's PATH.

Windows

Open a terminal in the project directory and run the batch file:

.\run.bat

Linux / macOS

Open a terminal in the project directory, make the script executable, and run it:

chmod +x run.sh
./run.sh

Output Waveform

Output Waveform Picture

About

I2C Master module written in SystemVerilog

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages