首页 > 其他分享 >数字集成电路设计实践 IIC-Slave接口芯片的全流程设计

数字集成电路设计实践 IIC-Slave接口芯片的全流程设计

时间:2024-08-22 16:47:56浏览次数:10  
标签:SCL Slave scl 主机 从机 SDA IIC 设计 I2C

数字集成电路设计实践  IIC-Slave接口芯片的全流程设计

一、 芯片设计方案

IIC原理

1. I2C协议

I2C协议由Philips公司推出。

1.1. 端口名称及含义

标准I2C只有2根信号线。

SCL:Serial CLock:串行时钟线,由主机产生并分享给从机。

SDA:Serial DAta:串行数据线,连接在主从机之间。把发送信号的一方叫做发送机,接收信号的叫做接收机。发送/接收机是随时改变的。

I2C仅有两根线,比SPI要简单得多。但是其代价为,SDA线的通信格式比较复杂,且相对固定。

1.2. 传输协议格式

1.2.1. 起始(S)和终止条件(P)

一般不区分起始条件和重复起始条件(S和Sr)。S和P的定义如下图。

 

1.2.2. 有效信号时间

如果在SCL=1期间SDA变动,那么必然是S/P,如果想要传输完整的信号,那么信号在SCL=1期间必须保持稳定,只能在SCL=0期间变化。

1.3. 传输格式

SDA线上传输的每次必须为一个字节的信息,可以传输多个字节。一个字节的信息可以是从机地址或者传输的信息。在每个字节的信息后都跟着从机的一位应答信号(ACK或A,从机拉低低信号为有效应答)。注意,在数据位,主机控制了SDA线;但在最后一位应答位时,发送机必须放出SDA线,让接收机去控制,如果接收机成功地拉低了,就说明接收机成功响应了

I2C协议先传输MSB。或者说,I2C是big endian传输的。

在完整的传输过程中,第一个字节一般是 “主机发送7位地址+主机发送R/W+从机Ack” 的格式,如下图所示。

其中第一个字节的七位具有一些预留的格式。这些预留的格式保证了I2C可以与CBUS协议兼容。

1.4. 多个主机连接时的线与机制

I2C要求连接到总线的接口输出端都为OD门(MOS工艺)或OC门(BJT工艺)。比如下图是OD门连接方式。

在OD门连接中,先假设只有一个主机连接,即输出端为 “上拉电阻+NMOS” 的组合,那么其输出必然是:

  1. NMOS开通,输出被拉低到0。
  2. NMOS关断,输出被电阻上拉到1。

现在再考虑多个主机连接的情况,一旦有一个NMOS开通,那么其他的NMOS管即使关断也没有用,电平一样会被拉下来,也就是 “输出只要有一个低,那么结果就是低” ,构成了 “线与” 的功能。这个线与功能是I2C完成仲裁的基础。

当然,这里只是从理论上描述一下I2C的OD门运行机制。具体还要看芯片的制造工艺、芯片管脚的电路模型等等。

1.5. 多主机连接时的仲裁机制

多个主机申请控制时的仲裁机制:

1.5.1. 多个主机的时钟同步

首先是多个主机的时钟如何同步。因为各个主机在SCL上也是用线与连接的,所以SCL的高低是可以确定的。

        产生的同步SCL时钟的低电平周期由低电平时钟周期最长的器件决定,而高电平周期由高电平时钟周期最短的器件决定。比如在上图中,即使CLK1先达到了高,但是因为SCL未到达高,因此CLK1需要等待至SCL变高,然后开始计时高电平时间,这样几个周期下来就完成了时钟同步。

1.5.2. 主机申请数据传输时的仲裁机制

        如下图是SCL相同时的SDA仲裁。在DATA2还处于低电平的时候,DATA1率先到达高,因此其丢失仲裁。丢失仲裁后,DATA1的输出级与SDA暂时断开,以免影响到DATA2的传输。

 

二 、芯片前端设计

I2C的VerilogHDL代码实现

I2C代码来自Copyright (C) 2008 Steve Fielding and OPENCORES.ORG

其基本思想是:利用一个时钟周期远小于SDA、SCL变化的时钟clk的边沿作为判断时刻。将整个I2C接口分为两个功能模块:串行传输线SCL和SDA信号的处理(serialInterface)、接收到SDA信号后存进移位寄存器完成串并转换的过程(registerInterface)。

真正困难的是如何读取SDA线上的信号,代码module名称为serialInterface.v,其思想是把每个可能性都转化为三段式状态机,根据状态机的流转,去做到 “判断开始/结束”“读数据”“Ack/NAck” 等功能。

2.1.1. 关于I2C SDA总线在芯片中的Pad的解释

I2C的SDA端口是一个双向接口,但是在芯片中,SDA只是一个Pad(意即只有一个管脚)。因此在芯片的输出管脚附近需要类似三态门的特殊的结构来让两个方向的信号互不干扰。

如上图所示,P是Pad,A是sdaOut,Y是sdaIn,PU是上拉使能,PU==1时允许上拉到电源。IE、OE本为输入/输出使能,但这里全部接高(即一直使能)。

如果从机希望把sda总线放掉,那么sdaOut必须在从机端口就被切断。如图中,当sdaOut<=0时,NMOS打开,输出被拉低,输出为0;当sdaOut<=1时,NMOS关闭,输出被PMOS拉高,为1。但是注意,此时的1是被电源和上拉电阻拉高的,因此可以再被拉低。这也就是说,只要sdaOut==1,sdaOut与SDA总线就是断开的。

如果需要多个从机,那么需要保证多个从机总共只有一个PU使能(OD门接法)。

关于sdaIn和sdaOut的关系,还可以从OD门的“线与”逻辑理解:

\[sdaOut=0\implies sda=sdaIn\cdot sdaOut=0 \]

\[sdaOut=1\implies sda=sdaIn\cdot sdaOut=sdaIn \]

下面很多代码以此为基础。这也是代码中始终没有出现过z高阻的理由。

以上说的是芯片中的一种特殊Pad。如果芯片没有用这种特殊Pad,那么就需要外挂上拉电阻。

因此使用I2C器件时一定注意查看Datasheet,确定是否需要上拉电阻。一种常见的上拉方式是:上拉4.7 K电阻到3.3 V电压。

2.1.2. serialInterface的流程图和代码解释

 

serialInterface.v就是控制从机对于SDA线的接收和发送。要接收或者发送的数据都暂存在register里面,由registerInterface控制传给serialInterface处理。

2.1.3. registerInterface的解释

控制着多个寄存器,这些寄存器每个都是一字节。寄存器的数量是不限制的,但是寄存器太多,地址就会变长,也会占用空间。对于本实验,甚至一个寄存器就足够了。

2.1.4. i2cSlave的连接和部分代码解释

以上是各个模块的连接方式。

此外,i2cSlave还有一些其它功能,比如说考虑实际延迟而做出的校正,比如对S/P的判断。下面解释一些代码块。

2.1.4.1. i2cSlave.v接口

 1 registerInterface u_registerInterface(
 2   .clk(clk),
 3   .addr(regAddr),
 4   .dataIn(dataToRegIF),
 5   .writeEn(writeEn),
 6   .dataOut(dataFromRegIF),
 7   .myReg0(myReg0),
 8   .myReg1(myReg1),
 9   .myReg2(myReg2),
10   .myReg3(myReg3),
11   .myReg4(myReg4),
12   .myReg5(myReg5),
13   .myReg6(myReg6),
14   .myReg7(myReg7)
15 );
16 
17 serialInterface u_serialInterface (
18   .clk(clk), 
19   .rst(rstSyncToClk | startEdgeDet), 
20   .dataIn(dataFromRegIF), 
21   .dataOut(dataToRegIF), 
22   .writeEn(writeEn),
23   .regAddr(regAddr), 
24   .scl(sclDelayed[`SCL_DEL_LEN-1]), 
25   .sdaIn(sdaDeb), 
26   .sdaOut(sdaOut), 
27   .startStopDetState(startStopDetState),
28   .clearStartStopDet(clearStartStopDet) 
29 );

2.1.4.2. rst复位功能

1 // sync rst rsing edge to clk
2 always @(posedge clk or posedge rst) begin
3   if (rst == 1'b1)
4     rstPipe <= 2'b11;
5   else
6     rstPipe <= {rstPipe[0], 1'b0};
7 end
8 
9 assign rstSyncToClk = rstPipe[1];

rst并不是一直使得电路reset的。如果rst保持很长时间的1,那么也只会复位一次。

容易画出电路的时序图。可以发现,rstSynToClk只在至多两个posedge clk时刻保持了高电平。这使得电路能够复位,但又不会在rst信号不撤去的时候一直复位导致电路无法运行。

2.1.4.3. debounce防抖逻辑

抖动,就是指上升/下降沿的时刻出现偏差。

根据代码i2cSlave_define.v的解释:

The rise time of SCL and SDA can be up to 1000ns (in standard mode), so it is essential to debounce the inputs.

也就是说,SCL和SDA的沿时间太长了,这使得在边沿变化过程中也可能遇到posedge clk,从而容易出现错误。我们希望在SCL/SDA的电平稳定了之后再进行采样。

debounce电路,就是常说的去抖滤波,主要用在芯片的PAD输入信号,或者模拟电路输出给数字电路的信号上。在本实验中,即SCL和SDA。

 1 // debounce sda and scl
 2 always @(posedge clk or posedge rstSyncToClk) begin
 3   if (rstSyncToClk == 1'b1) begin
 4     sdaPipe <= {`DEB_I2C_LEN{1'b1}};
 5     sdaDeb <= 1'b1;
 6     sclPipe <= {`DEB_I2C_LEN{1'b1}};
 7     sclDeb <= 1'b1;
 8   end
 9   else begin
10     sdaPipe <= {sdaPipe[`DEB_I2C_LEN-2:0], sdaIn};
11     sclPipe <= {sclPipe[`DEB_I2C_LEN-2:0], scl};
12     if (&sclPipe[`DEB_I2C_LEN-1:1] == 1'b1)
13       sclDeb <= 1'b1;
14     else if (|sclPipe[`DEB_I2C_LEN-1:1] == 1'b0)
15       sclDeb <= 1'b0;
16     if (&sdaPipe[`DEB_I2C_LEN-1:1] == 1'b1)
17       sdaDeb <= 1'b1;
18     else if (|sdaPipe[`DEB_I2C_LEN-1:1] == 1'b0)
19       sdaDeb <= 1'b0;
20   end
21 end

显然,debounce只有在信号电平变化之时才需要。在代码中,设立一个reg,称作xxxPipe,预设全为1。然后该数字序列会随着时钟一直刷新,直到整个序列变得一致为止,这说明电平已经稳定了。

而xxxDeb代表了debounce后给出的电平判断结果。

2.1.4.4. 信号延时

 1 // delay scl and sda
 2 // sclDelayed is used as a delayed sampling clock
 3 // sdaDelayed is only used for start stop detection
 4 // Because sda hold time from scl falling is 0nS
 5 // sda must be delayed with respect to scl to avoid incorrect
 6 // detection of start/stop at scl falling edge. 
 7 always @(posedge clk or posedge rstSyncToClk) begin
 8   if (rstSyncToClk == 1'b1) begin
 9     sclDelayed <= {`SCL_DEL_LEN{1'b1}};
10     sdaDelayed <= {`SDA_DEL_LEN{1'b1}};
11   end
12   else begin
13     sclDelayed <= {sclDelayed[`SCL_DEL_LEN-2:0], sclDeb};
14     sdaDelayed <= {sdaDelayed[`SDA_DEL_LEN-2:0], sdaDeb};
15   end
16 end

延时的道理很简单,把debounce后的信号电平放到序列的最后一位,随着时间逐渐左移,这样就完成了延时。

在i2cSlave_define.v文件中,可以看到: \(t_{debounce}=t_{delay,scl}=2.5t_{delay,sda}\)

正如代码注释所说,scl做延时是为了比sda延时更多;sda做延时是为了检测S/P。在scl和sda都进行了debounce之后,波形如图下图所示:

原来sda的边沿与scl边沿可能贴得很近,但是由于不同的延时,sclDeb和sdaDeb的边沿差距很大,这样S/P的判断就很难出现错误了。

2.1.4.5. 判断S/P

 1 // start stop detection
 2 always @(posedge clk or posedge rstSyncToClk) begin
 3   if (rstSyncToClk == 1'b1) begin
 4     startStopDetState <= `NULL_DET;
 5     startEdgeDet <= 1'b0;
 6   end
 7   else begin
 8     if (sclDeb == 1'b1 && sdaDelayed[`SDA_DEL_LEN-2] == 1'b0 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b1)
 9       startEdgeDet <= 1'b1;
10     else
11       startEdgeDet <= 1'b0;
12     if (clearStartStopDet == 1'b1)
13       startStopDetState <= `NULL_DET;
14     else if (sclDeb == 1'b1) begin
15       if (sdaDelayed[`SDA_DEL_LEN-2] == 1'b1 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b0) 
16         startStopDetState <= `STOP_DET;
17       else if (sdaDelayed[`SDA_DEL_LEN-2] == 1'b0 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b1)
18         startStopDetState <= `START_DET;
19     end
20   end
21 end

因为给serialInterface的rst=rstSynToClk | startEdgeDet,所以在startEdgeDet<=1时serialInterface会reset,从机状态置为START。

i2cSlave_define.v注释:

SDA should have a minimum of 100ns of set up time, with respect to SCL rising edge. But with the very slow edge speeds used in I2C it is better to err on the side of caution.

i2cSlave.v注释:

Because sda hold time from scl falling is 0ns, sda must be delayed with respect to scl to avoid incorrect detection of start/stop at scl falling edge.

在sclDeb==1时可以检测S/P。假如说主机给入的是上图所示的信号,那么在SCL下降时刻SDA基本也就开始变化了,因此这样不太稳妥,容易导致在SCL为高有效时采不到正确的数据。因此,在I2C从机内部把SCL延迟地比SDA多一些,就会解决这个问题。

同时因为SDA信号被寄存器存下来了,因此后面可以慢慢用来判断S/P,而不用担心边沿过去了。

2.1.5. i2cSlaveTop的解释

i2cSlaveTop.v就是完全把i2cSlave的功能封装起来。除了I/O配置、实例运用,没有加入新的功能。

2.1.6. 代码的Verilog仿真

在仿真中,认为方波边沿时间为0,对于数字电路,这个假设是合理的,因此后面的仿真一直如此。

在实际的芯片配置和PCB连接中,sdaIn和sdaOut是用OD门连在一起的。但是在代码仿真里不需要考虑这些,它们是完全独立的信号。

进行代码仿真(Xilinx Vivado):

在图中,sdaIn==1’bz的时间是等待从机Ack的时间(虽然因为两条线是分开的,sdaIn是多少其实无所谓的,不过用来区分开每个字节也不错)。

可以看到,内容依次为:

传输位数

传输的方向以及字节内容

传输代表的意义

/

scl=1期间,sdaIn下降

S(开始信号)

8

主机向从机写0111_1000

主机寻从机址011_1100(7’h3c),R/W=0(W)

1

主机等待从机应答

从机给出应答Ack

8

主机向从机写0000_0010

主机寻寄存器址0000_0010(8’h02),即myReg02

1

主机等待从机应答

从机给出应答Ack

8

主机向从机写1010_0110

主机向从机寄存器myReg02写数据1010_0110

1

主机等待从机应答

从机给出应答Ack

8

主机向从机写0011_0110

主机向从机寄存器myReg03写数据0011_0110

1

主机等待从机应答

从机给出应答Ack

/

scl=1期间,sdaIn上升

P(结束信号)

不限

任务结束,从机空闲

/

scl=1期间,sdaIn下降

S(开始信号)

8

主机向从机写0111_1000

主机寻从机址011_1100(7’h3c),R/W=0(W)

1

主机等待从机应答

从机给出应答Ack

8

从机向主机写1010_0110

从机向主机发送myReg02数据(Addr复位时默认置8’h02)

1

从机等待主机应答

主机给出不应答Nak,代表从机发送终止

注意:后面即使再用主机给出Ack去尝试激活从机继续发送数据,那也没用了。从机发送被主机终止,这个任务就已经结束了,只是主机还没有给出结束信号。

 

       可以大概计算一下各信号宽度。I2C标准的传输速率为100 Kb/s(S)、400 Kb/s(F)、3.4 Mb/s(Hs),其实传输速率指的就是SCL时钟频率,因为每个SCL周期传输1 bit数据,分别计算其每位宽度为10 μs、2.5 μs、294.12 ns。在图示代码中用200ns作scl半周期,运行完全没有问题,因为clk半周期设为5 ns,相比与scl、sda来说太小了。所以速率的问题应该不用担心。

      标准传输速率其实表示的只是芯片能容许的最大SCL传输速率,如果实际SCL速率比标称速率高就可能无法正常传输,因为此时可能不满足时钟clk频率远大于SCL频率这一条件。实际上,SCL总是由主机提供给从机,所以只要从机的标称速率能达到主机提供的SCL速率,从机接收(接收数据也是主机给的,必然与SCL速率吻合)或发送的数据率都能匹配SCL速率。

      I2C标准的clk时钟频率好像没有标准的要求,只要比SCL、SDA频率高得多即可。为了和整个芯片的200 MHz内置频率匹配,可采用四分频,即50MHz的频率,也比较接近。经过测试,在20ns的clk周期下,scl周期设为1 μs,是完全没有问题的。一般I2C传输速率都在 百K~几M 频率范围内,而提供给从机模块的时钟最小也有几十MHz,因此此模块在任何情况下基本都能工作。

这里I2C也不太纠结速率,也不太纠结速率是否标准,因此上述数据就可以了。

 

状态机:

数据通道:

 

 

 

 

 

 

标签:SCL,Slave,scl,主机,从机,SDA,IIC,设计,I2C
From: https://www.cnblogs.com/VeriMaverick/p/18374252

相关文章

  • 基于ssm+vue.js的校园二手交易平台附带文章和源代码设计说明文档ppt
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我成功案例代码参考数据库参考源码获取前言......
  • 课程设计之在线课堂管理平台的设计与实现【完整版】
    一、需求分析1.1需求来源通过研究传统的课堂学习特点,了解到传统课堂教学中存在教师与学生沟通不便,通知与作业不能及时传达,教学资源不能高效共享等不足,本项目使用JavaEE技术来解决上述需求。此项目贴近我们高校学生生活,可以从平时的课堂教学存在的优缺点来获取并定义部分......
  • java+vue计算机毕设农资电子监管系统的设计与实现【源码+开题+论文】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着农业现代化的不断推进,农资产品的流通与管理成为保障农业生产高效、安全的重要环节。传统农资管理模式存在信息不对称、监管难度大、效率低下等问......
  • 【系统架构设计】软件架构设计(1)
    【系统架构设计】软件架构设计(1)软件架构概述架构需求与软件质量属性软件架构风格数据流风格批处理序列管道-过滤器2者风格比较仓库风格--黑板系统层次系统架构风格二层及三层C/S架构风格MVCMVP面向服务的架构架构设计软件架构文档化软件架构评估构件及其复用产品线及......
  • 软考-软件设计师(程序设计语言习题)
       ......
  • 基于spring boot的幼儿园管理系统的设计与实现:幼儿园管理系统(源码+文档)
    目录一.研究内容和目的二.开发工具三.开发框架介绍四.系统需求分析五.幼儿园管理系统结构设计六.数据库设计七,系统页面展示八.源码获取一.研究内容和目的研究内容:本文基于SpringBoot框架设计和实现幼儿园管理系统,主要包括以下内容:幼儿园管理系统需求分析对幼儿园......
  • 设计模式简介及PHP的35种设计模式(上)
    什么是模式??        有经验的00开发者(以及其他的软件开发者)建立了既有通用原则又有惯用方案的指令系统来指导他们编制软件。如果以结构化形式对这些问题、解决方案和命名进行描述使其系统化,那么这些原则和习惯用法就可以称为模式。例如,下面是一个模式样例:    ......
  • 免费【2024】springboot 旅游攻略系统实现APP的设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 免费【2024】springboot 基于Android的个人财务系统的设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 免费【2024】springboot 环境保护生活APP的设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......