Menu Close

I2C 主设备PHY层启动及读写控制Verilog程序设计

在I2C发起读/写过程之前,主设备会先发起I2C的启动(START), 从设备的地址匹配(从设备地址写),I2C的读/写控制以及从设备应答检测的等一系列过程。由于无论是I2C读还是I2C写,该部分的操作过程都是必须的,因此把该部分内容单独作为一个模块进行设计,便于代码的重用。时序如图1:

图1

1.I2C启动部分主设备程序设计

  • 接口要求:

    • 复位信号,系统时钟,系统时钟分频(由于I2C不同速度匹配)
      • input rst,
      • input sys_clk,
      • input clk_en, clk_en_half,
    • 从设备地址、启动信号、读/写标志(即该段程序之后的I2C 总线行为
      • input [7:0] data_in,  // {dev_addr[6:0], 1’b0/1’b1}
      • input [1:0] op_cmd, // 2’b00 means START + dev_addr + R/W
      • input op_cmd_en,   // op_cmd enable , sys_clk single pulse
    • I2C 总线的内部信号:由于inout信号一般只在端口使用,因此在FPGA的内部逻辑(内部模块)将会把inout(双向口)变换成input, output类型进行传递
      • input sda_i,
      • output sda_o,
      • output sda_t,
      • input scl_i,
      • output scl_o,
      • output scl_t,
    • 握手信号:op_cmd_done 操作完成、从设备应答。当op_cmd_done产生,从设备应答后(dev_ack)同时送给上层模块。op_cmd_done 保持一个sys_clk 时钟宽度。
      • output op_cmd_done, // operation finished
      • output reg dev_ack//从设备是否有应答
  • 总体接口如下:

module i2c_addr(

input sys_clk,

input [1:0] op_cmd,
input op_cmd_en,
output reg op_cmd_done,

output reg dev_ack,
input [7:0] data_in,

input clk_en,
input clk_en_half,

output reg sda_t,
output sda_o,
input sda_i,

output reg scl_t,
output scl_o,
input scl_i,

input rst

);

  • 主体程序设计

该部分程序实现的主体内容如下:初始化,在IDLE状态下检测启动请求(op_cmd = 2’b00),对从设备的地址与读写控制信号移位进行串行化,等待从设备应答。串行化期间对SCL,SDA的要求是,在SCL为高电平期间SDA保持不变(start除外),SDA的任何变化都在SCL为低电平的时段发生。程序的流程图如下:

图2

  • 程序代码如下:

  • iic_phy 模块代码


 

  • 将设计的模块例化,并组装到 iic_engine的模块中,这样就可以使用SCl_en模块,充分利用以设计的成果,逐步组装成程序代码及接口如下:


 

  • 仿真程序设计:


 

仿真程序中使用at24c02D IP ,这个IP 是由厂家提供的,这里我们只是使用这个I2C EEPROM ip 核。 IP核具体信息,可以参考文章https://www.microchip.com/en-us/product/AT24C02D

图3

注意,厂家提供的verilog IP ,目前只能在vivado下或者是questaSim 下仿真。 在quartus下或者在modelsim,questaSim_starter下不能仿真。(有些仿真语法不支持)。

在仿真工程中,我们主要学习三态门如何在仿真程序中仿真。

  • 仿真结果

仿真波形如图4

图4

从图4可以看出在写阶段串行了1010_001(地址)及0(写控制)。24c02 iic设备应答。在I2C PHY层 Verilog程序结构化设计中介绍过op_cmd 定义:op_cmd[1:0] = 2’b00;代表start + write + dev_ack。 op_cmd[1:0] 和op_cmd_en 同时由仿真程序发出,当iic_phy完成相关操作后,返回op_cmd_done 信号, 代表当前操作命令(op_cmd)完成。

 

Posted in FPGA, FPGA 教材教案, Quartus II, Verilog, 开发语言, 教材与教案, 文章, 编程语言, 集成电路