1 整体功能
通过I2C:
1、向E2PROM存储器地址0~255依次写入数据0~255;
2、从E2PROM存储器地址0~255依次读出数据;
3、如果读出的值全部正确,则LED灯常亮,否则 LED 灯闪烁。
该代码已在Vivado工程上编译通过,且下载到板卡上验证正确,想要获取整个工程或者技术交流,可以关注公众号,然后发送消息私聊哈。
2 顶层模块
2.1接口定义
2.2公共参数定义
这里可以设置器件地址、I2C速率、读写的字节个数等;
2.3产生100MHz时钟
2.4模块例化:e2prom读写测试模块
2.5模块例化:i2c驱动模块
这是I2C协议的具体部分:
2.6模块例化:led指示模块
3 子模块详解
3.1 e2prom读写测试模块
3.1.1接口定义
3.1.2读写测试逻辑
1、先进行复位初始化,此时写入地址、数据、触发执行信号都是0;
2、在用case语句进行条件选择控制;
1)首先在2'd0条件:通过计数器(wait_cnt)等待一个时间间隔,计数器(flow_cnt)才能计数,且触发执行信号变成1,此时i2c驱动模块会执行写入操作(写入0);
2)然后转入2'd1条件:等待i2c驱动模块给到i2c_done信号后,将计数器写入地址、数据都+1,同时(flow_cnt)变成0,又进入2'd0条件;如此往复执行256次后,即完成向存储器地址0~255分别写入数据0~255;
3)然后地址清零,执行读操作,并转入2'd2条件:触发执行信号变成1,此时i2c驱动模块会执行读操作(地址为0),计数器(flow_cnt)+1;
4)然后转入2'd3条件:等待i2c驱动模块给到i2c_done信号后,执行数值比较逻辑,如果读取错误或者应答失败,执行rw_done <= 1'b1;rw_result <= 1'b0;此时一直处于2'd3条件,但由于i2c驱动模块给到i2c_done信号不再有效,所以会一直处在2'd3条件,不再执行任何操作;如果读取正确,则将地址、数据都+1,又进入2'd2条件;如此往复执行256次后,即完成读取存储器地址0~255中的数据,然后执行rw_done<= 1'b1;rw_result <= 1'b1; 此时一直处于2'd3条件,但由于i2c驱动模块给到i2c_done信号不再有效,所以会一直处在2'd3条件,不再执行任何操作;
3.2 i2c驱动模块
3.2.1接口定义
3.2.2产生SCL四倍频率驱动时钟
3.2.3三段式状态机
3.2.3.1 同步时序描述状态转移
采用的是SCL四倍频率驱动时钟
3.2.3.2 组合逻辑判断状态转移条件
1、复位初始化后:进入空闲状态(st_idle);
2、触发执行信号到来后:进入发送器件地址状态(st_sladdr);
3、从机应答后:进入发送位字地址(8:st_addr8,16:st_addr16)状态;
4、从机应答后:如果是写操作,进入写状态(st_data_wr);如果是读操作,进入读状态(st_addr_rd);
5、如果在写状态(st_data_wr):从机应答后,进入结束I2C操作状态(st_stop);
6、如果在读状态(st_addr_rd,需要先发送一个器件地址):从机应答后,进入读数据状态(st_data_rd);
7、如果在读数据状态(st_data_rd):从机应答后,进入结束I2C操作状态(st_stop);
8、如果在结束I2C操作状态(st_stop):从机应答后,进入空闲状态(st_idle);
3.2.3.3 时序电路描述状态输出
采用的是SCL四倍频率驱动时钟;
1、先进行复位初始化,此时总线为高(scl、sda_out),主机发送(sda_dir=1),其余诸信号都为0;
2、然后进入case条件选择状态:
1)首先在st_idle状态:在给到触发执行信号后,准备好写入的字地址、字数据;同时跳转到st_sladdr状态(组合逻辑控制跳转的);
2)st_sladdr状态:通过计数器(cnt),依次送出器件地址(高位在前),同时给出应答信号(i2c_ack),进入st_addr16/st_addr8状态(由bit_ctrl控制);
3)以st_addr8状态为例:通过计数器(cnt),依次送出字地址(高位在前),同时给出应答信号(i2c_ack),如果是写进入st_data_wr状态,如果是读进入st_addr_rd状态;
4)st_data_wr状态:通过计数器(cnt),依次送出字数据(高位在前),同时给出应答信号(i2c_ack),进入st_stop状态;
5)st_addr_rd状态:通过计数器(cnt),依次送出器件地址(高位在前),同时给出应答信号(i2c_ack),进入st_data_rd状态;
6)st_data_rd状态:通过计数器(cnt),依次读出字数据(高位在前),同时给出非应答信号,进入st_stop状态;
7)st_stop状态:通过计数器(cnt),主机发送停止信号,进入st_idle状态;