微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 关于IIC通信协议的从机Verilog实现

关于IIC通信协议的从机Verilog实现

时间:10-02 整理:3721RD 点击:
大家好,本小白最近遇到一个搞不明白的问题。希望大神指点江山~      目前项目涉及到IIC通信协议,主机部分是实现发送8位器件地址,8位的寄存器地址,16位数据的读写。主机的功能通过一个EEPROM的行为模型仿真验证通过,但是行为模型不可以综合。项目里涉及到的主机由于是非标准IIC协议,就是发送字节的时序不是按照标准的IIC时序。相对应的从机也是根据非标准的IIC进行写的。目前遇到的主要问题是把主机修改成标准IIC协议时序,这一块的工作已经完成。
      亟待解决的问题是,从机代码修改。之前使用的从机主要是有两个问题需要解决:一,时序按照标准IIC主机进行修改。二,之前使用的从机代码用的是自己的晶振clk进行驱动,标准的IIC从机应该是根据主机发送过来的SCL进行数据流的控制,不要自己再加时钟。但是起始信号和终止信号,以及向主机发送应答信号和接受主机发送过来的应答信号该如何用SCL进行数据控制呢?如果是在SCL的上升沿就行数据的读取,SCL的下降沿进行SDA数据总线的数据变化,那么起始信号和结束信号如何用可综合的代码实现呢?

之前也一直遇到这个问题,从机如果只有SCL时钟驱动的话,从机中所有信号肯定也是跟随SCL跳变的,包括SDA信号,这样就很难满足iic的时序要求了。一直不知道这块怎么解决,实际IIC项目中是只有SCL这一个时钟吗?忘大神解答

标准的IIC主机和从机,都不会以SCL所为实际时钟去驱动逻辑。SCL和SDA的逻辑都是在另外的较高频率时钟下产生得到的。


原来如此,现在遇到的问题是i2c协议要求的scl和sda都是线与逻辑,但是这个线与逻辑verilog不好定义啊,我现在想把这个scl和sda定义为wand线型,这种线型可用于前仿真,但是不能综合,实际工程应该怎么做这一块呢?



   不论主从设备,SCL/SDA的PAD都做成开漏即可,这样在一个master多个slave的应用中就不会出现总线冲突了,不是你理解的那种线与。



  那如果前期写代码的时候我想看看仿真功能对不对,但是nc和modlesim都不能仿真这种开漏的器件啊,我要怎么看波形呢?

If IIC used SCL as clock source only, it must use real gate IP cell and design as full custom way

lsss讲的绝对了点,其实可以用scl作为时钟,但是复位信号要比较特殊,要用sda作为时钟来产生scl,opensource上有参考设计的,暂时找不到链接了, 给你贴部分代码
assign sas_resetn = scl | sda_in;
//I2C start
always @(negedge sda_in or negedge sas_resetn)
begin
    if(!sas_resetn)     i2c_start <= 1'b0;
    else if(scl)        i2c_start <= 1'b1;
    else                i2c_start <= 1'b0;
end
//I2C stop
always @(posedge sda_in or negedge sas_resetn)
begin
    if(!sas_resetn)     i2c_stop <= 1'b0;
    else if(scl)        i2c_stop <= 1'b1;
    else                i2c_stop <= 1'b0;
end
再用start和stop产生复位信号
assign comb_reset = i2c_start | i2c_stop ;
就可以用来复位scl做始终所驱动的逻辑了


非常的感谢,我现在对从机的思路还是很不明显。比如,根据标准的IIC协议,在主机对从机进行read操作的时候,需要有第二次的起始信号的检测,如果是这样的话和第一次的起始信号怎么分别呢?用状态机进行从机的描述还是数据流?状态机的话我从机的状态跳转就有些分不清楚,数据流的话我都算用计数器,对SCL的边沿进行计数,然后根据计数器进行数据的收发, 但是面对的问题是write和read计数器怎么弄?read的前几个字节和write是一样的,就是在第二次启动信号之后开始写入read控制字节,然后进行read从机的数据。这个计数器怎么弄?如果是用状态机的话,状态的跳转是基于scl还是基于sda呢?

买夏宇闻的数字电路设计,有IIC设计的RTL设计验证实例,你看看就明白了。



   内部需要记录当前状态,比如读需要两次操作,那你第一步发送地址完成了需要用一个寄存器bit记录下当前状态,第二步就按照读数据的操作来了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top