STA series --- 6 .Crosstalk and Noise

序:

本篇内容,基于阅读J. Bhasker • Rakesh Chadha著作《Static Timing Analysis for Nanometer Designs》后进行的总结以及自己的观点和感想,如有不正确的地方,还请指点。读者有微电子基础将更好理解内容。(图片内容绝大部分直接引用书中)

在先进工艺节点下,对于STA的check,通常会引入SI(signal integrity)分析,而在报告中也会查看noise相关的报告,本章节就针对noise/SI进行一个回顾。noise是指周围信号对该信号产生的影响,可能会导致改正常传输的信号出现错误传输,从而影响到芯片的稳定性。

6.1 overview

噪声/noise到底是什么东西,其实可以理解为干扰,在真实的版图或者真实的工艺制造过程中,每一个cell周围都会有非常多的其他cell,cell之间并非毫无影响,可能会产生干扰。同理,path之间也是,每一条走线周围可能有十条甚至上百条的走线,都会对该条走线产生干扰。产生干扰的结果有两种:glitch/毛刺和delay延迟。 如下图所示,正常波形和收到noise影响的波形,产生的glitch可能会导致信号传输错误,而造成的delay延迟增大可能导致timing不满足。噪声是信号之间的相互影响,受影响的信号一般称为victim,而影响者一般称为aggressor

在这里插入图片描述
那什么是造成噪声影响的主要因素呢?
1)金属层增加,工艺节点越高,用到的金属层越多,相应的互连线也就越多
2)高宽长比的金属连线占主导,垂直走线越来越多,导致侧壁耦合电容增加
3)高density,随着对性能和继承读要求的增加,密度增加,导致互连线也增加
4)高频,由于高频要求,导致信号转换速度要求更高,更容易产生耦合效应
5)低压,低压导致noise 窗口变小

6.2 Crosstalk Glitch Analysis

6.2.1 basic

接下来详细看一下glitch相关的内容。上一节提到施害者和受害者。施害者和受害者之间存在耦合电容,那么在施害者信号高低变化时,就会通过耦合电容在受害者上面产生毛刺,比如把原本的受害者net上的信号0变成了1,或者1变成了0,而信号被时序逻辑捕获或者影响了时序逻辑,都可能产生很严重的后果。影响毛刺的大小的因此由很多:
1)耦合电容越大,毛刺幅度越大
2)施害者信号的slew越快,毛刺幅度越大
3)受害者接地电容越小,毛刺幅度越大
4)受害者前级驱动越弱,毛刺幅度越大

6.2.2 glitch type

施害者电平切换和受害者电容高低都存在两种情况,那么产生的glitch就一共有四种情况,分别为overshoot glitch,undershoot glitch,rise glitch,fall glitch如下图所示:

在这里插入图片描述

6.2.3 Glitch Thresholds and Propagation

是否所有的毛刺都不可以被接受?是否所有的毛刺都可以一直朝后传播?并不是这样的。
● DC Thresholds
如果单纯只考虑noise 的幅度,如下图所示,当rise glitch,高于了Vil_max,fall glitch低于了Vih_min,定义这样的毛刺为危险毛刺,可能会超后级传播,而在这个范围以外的毛刺,被认为是安全毛刺。这个是dc噪声裕度。这样的设定并不是非常合理。并不能保证,安全毛刺一定安全,而危险毛刺一定有问题。因为此处只考虑了毛刺的高度,而并没有考虑毛刺的宽度和输出负载

在这里插入图片描述 在这里插入图片描述
● AC Thresholds
单纯靠DC 阈值来卡毛刺,那对于设计来说挑战是很大的,因为很多毛刺虽然幅度很高,但是可能非常非常的窄。对于一个cell本身就有延迟,而当本身的延迟要远大于输入的毛刺时候,那么毛刺是不会通过cell传播到后级的,因为在后级还没反应完,毛刺可能已经结束了。另外,增加cell 的负载,同样增加cell delay,一样能够消除毛刺。如下图所示的AC 给出的噪声容限相对来说就更加合理,对于glitch很窄,或者glitch宽度很低(极限对应DC阈值)的情况,noise是可以忽略的,即图中的safe glitch所示。如何消除毛刺,可以通过增加cell的负载,从而增加noise margin,但这种属于杀敌一千,自损八百的做法。通常STA阶段都是通过增强受害者前级驱动的方法消除noise。
在这里插入图片描述
如果毛刺超过AC阈值,那么毛刺就会通过单元超后级传播。输出毛刺的高度和宽度是输入毛刺的宽度、高度以及输出负载的函数。即输入毛刺形状和输出负载,决定了输出毛刺的形状。而这些函数表征,在标准单元库中的propagated_noise模型是由描述的。

6.2.4 Noise Accumulation with Multiple Aggressors

前面提到的glitch,只是讨论了一个施害者对一个受害者的影响,那么在实际的电路中,一个受害者可能对应数个施害者,对于如此情况,如果对多个可能产生的glitch进行评估?
如下图所示,考虑时序相关,假设在如下时刻,同一个受害者受到4个不同施害者的“迫害”,产生了4个glitch,那么noise的计算应该如何考量呢?当然最坏的情况,是四个加起来那么就是0.53,当然这样是最悲观的情况,因为4个glitch并非同时产生。我们看同时产生的时候,可以看到A3+A4=0.32是最坏的情况。因此在去除悲观度的情况下,noise加起来是0.32的毛刺幅度。
在这里插入图片描述
另外在考虑noise累加时候,还需要考虑功能逻辑从而减少悲观度。如扫描控制逻辑和功能逻辑,他们之间不可能同时开始工作,因此他们之间相互的noise影响是可以忽略不计的。再比如某一条net,可能从reset之后就一直保持一个定值,那么它不可能称为一个施害者等等这些,在STA的noise检查中都会有考虑进去。

6.3 Crosstalk Delay Analysis

6.3.1 basic and delay type

上面一节讲解的是noise造成的glitch问题,出现在施害者电平变化对受害者电平值的影响,从而对功能逻辑产生影响。还有一种情况是施害者的高低电平变化对受害者的高低电平变化产生的应,这种会带来单元传输数据快慢的影响,对STA产生影响。如下图所示为施害者和受害者电平同时刻发生变化的情况。

在这里插入图片描述

分为两种情况,positive-crosstalk和negative-crosstalk。从图上可以看出,postive 指的是delay增加的影响,也就是上升沿影响下降沿,下降沿影响上升沿,negative则恰恰相反。对于postive-crosstalk,可以会造成slew退后,导致slew变大,由于cell delay的计算受到input tran和output cap知道,slew越大,那么对应的cell delay值也就越大,因此,postive-crosstalk的情况,是利于hold的,但是不利于setup。而negative-crosstalk则相反,导致delay变小,利于setup check,不利于hold check。

6.3.2 Accumulation with Multiple Aggressors

关于对delay影响的累加衡量方式和glitch是类似的,此处就不再赘述。

6.4 Timing Verification Using Crosstalk Delay

上面造成延迟的两类crosstalk,细分为4类即为:

● 正上升延迟(Positive rise delay):上升沿提前到达
● 负上升延迟(Negative rise delay):上升沿滞后到达
● 正下降延迟(Positive fall delay):下降沿提前到达
● 负下降延迟(Negative fall delay):下降沿滞后到达

delay的快慢直接影响到了setup 和hold check,对于data path ,setup当然期望越快越好,hold则相反,对于capture clk path,setup期望不要太短,hold则相反。因此cell收到noise影响导致的delay变化,对于timing check会有直接影响。详细的参考
对于setup check:
按照严格的检查方式,期望的是launch clock path和data path为postive-crosstalk,从而使得launch和data path变长;capture clock path为negative-crosstalk,从而使capture path变短,这样可以使得setup timing 变差
对于hold check:
按照严格的检查方式,期望的是launch clock path和data path为negative-crosstalk,从而使得launch和data path变短;capture clock path为postive-crosstalk,从而使capture path变长,这样可以使得hold timing 变差
具体的关于setup/hold timing 情况,可以参考Timing Check – hold/setup check原理介绍

6.5 Computational Complexity

对于寄生参数的提取以及对于噪声影响的计算,并不是一个简单的事情,需要耗费大量的物理资源,因此当先进工艺下,引入了noise的影响时候,STA的难度也相应增加很大,对于大的design,如果有效处理?

分层设计与分析
4.5节已介绍了可用于验证大型设计的分层方法(Hierarchical Methodology),类似的方法也可用于降低提取寄生参数和进行分析的复杂性。对于大型设计,运行(run)一次通常无法实现寄生参数的提取。每个层级模块的寄生参数可以分别提取,这又需要在设计实现的时候使用了分层设计方法。这意味着在分层模块内部的信号与模块外部的信号之间不存在耦合,这可以通过不在模块边界上布线或通过在模块上添加屏蔽层来实现。另外,信号网络不应该布在靠近模块边界的地方,并且任何布线网络都应在靠近模块边界的地方进行屏蔽保护,这样可以避免与其他模块的网络耦合。

耦合电容的过滤
在噪声计算过程中,对于一些非常小的噪声,是直接过滤掉的,而不是参与计算,可以有效优化计算时间。
过滤的原则:
● 较小的值:在串扰或噪声分析中,可以忽略非常小的耦合电容,例如低于1fF。在提取过程中,数值较小的耦合电容可以视为接地电容。
● 耦合比:耦合对受害者网络的影响是基于耦合电容相对于受害者网络总电容的相对值。具有较小耦合比(例如低于0.001)的施害者网络可以从串扰延迟分析或串扰毛刺分析中排除。
● 合并小型攻击者:可以将影响很小的多个攻击者映射为一个较大的虚拟攻击者。这可能有点悲观,但可以简化分析。可以通过切换攻击者的子集来缓解一些悲观度,攻击者的确切子集可以通过统计方法来确定。

6.6 Noise Avoidance Techniques

能不能从根本上面去避免这种噪声,也就不需要在check时候进行计算了。一些屏蔽噪声的物理手段:
● 屏蔽(Shielding):此方法要求将屏蔽线放在关键信号的两侧,屏蔽线已连接到了电源或地。关键信号的屏蔽确保了关键信号没有有效的攻击者,因为在同一金属层中最相邻的走线是处于固定电位的屏蔽走线。尽管在不同的金属层中可能存在来自布线的某些耦合,但是大多数耦合电容还是由于同一层中的电容耦合引起的。由于不同金属层(上方和下方)通常会正交走线,这样跨层的电容耦合会最小化。因此,将屏蔽线放置在同一金属层中可确保关键信号的耦合最小。如果由于布线拥塞而无法使用接地或电源线进行屏蔽,则可以把在功能模式下保持不变、电平切换不频繁的信号(如扫描控制信号)布线为关键信号的直接相邻信号。这些屏蔽方法可确保不会由于相邻网络的电容耦合而产生串扰。
● 线距(Wire spacing):这减少了与相邻网络的耦合。
● 快速压摆(Fast slew rate):网络上的压摆较快表示该网络不易受到串扰的影响。
● 保持良好的稳定电源(Maintain good stable supply):这对于串扰而言并不重要,但对于最大程度地减少由于电源变化而引起的抖动至关重要。由于电源上的噪声,可能会在时钟信号上引入大量噪声。应该添加足够的去耦电容,以最大程度地减少电源上的噪声。
● 保护环(Guard ring):衬底(substrate)上的保护环(或双重保护环)有助于将关键的模拟电路与数字噪声隔离开来。
● 深n阱(Deep n-well):与上面类似,因为在模拟部分具有深n阱,有助于防止噪声耦合到数字部分。
● 隔离块(Isolating a block):在分层设计流程中,可以将布线晕圈(halos)添加到块的边界;此外,还可以将隔离缓冲器(isolation buffers)添加到块的每个IO中。

6.5-6.6都是一些陈述性内容,直接参考的翻译内容

  • 5
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是使用USART通信实现STM32与GY-53-L1测距模块进行通信的示例代码: ``` #include "stm32f10x.h" #include <stdio.h> // 定义USART相关的GPIO口 #define USARTx USART1 #define USARTx_CLK RCC_APB2Periph_USART1 #define USARTx_TX_PIN GPIO_Pin_9 #define USARTx_TX_GPIO_PORT GPIOA #define USARTx_TX_GPIO_CLK RCC_APB2Periph_GPIOA #define USARTx_RX_PIN GPIO_Pin_10 #define USARTx_RX_GPIO_PORT GPIOA #define USARTx_RX_GPIO_CLK RCC_APB2Periph_GPIOA // 定义USART接收缓冲区大小 #define USART_RX_BUF_SIZE 100 // 定义发送和接收状态 #define USART_SENDING 0 #define USART_RECEIVING 1 // 定义USART接收缓冲区 uint8_t USART_RX_BUF[USART_RX_BUF_SIZE]; uint16_t USART_RX_STA = 0; uint8_t USART_RX_STATUS = USART_RECEIVING; // USART初始化函数 void USART_Config(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(USARTx_CLK | USARTx_TX_GPIO_CLK | USARTx_RX_GPIO_CLK, ENABLE); // 配置USARTx_TX的GPIO口 GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure); // 配置USARTx_RX的GPIO口 GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USARTx, &USART_InitStructure); USART_Cmd(USARTx, ENABLE); } // USART发送一个字节 void USART_SendByte(USART_TypeDef *USARTx, uint8_t byte) { while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); USART_SendData(USARTx, byte); } // USART发送字符串 void USART_SendString(USART_TypeDef *USARTx, char *str) { while (*str) { USART_SendByte(USARTx, *str++); } } // USART接收中断处理函数 void USART1_IRQHandler(void) { uint8_t ch; if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { ch = USART_ReceiveData(USART1); // 如果接收到换行符,则表示一行数据接收完成 if (ch == '\n' || ch == '\r') { USART_RX_BUF[USART_RX_STA++] = ch; USART_RX_STATUS = USART_SENDING; } else { USART_RX_BUF[USART_RX_STA++] = ch; if (USART_RX_STA >= USART_RX_BUF_SIZE) { USART_RX_STATUS = USART_SENDING; } else { USART_RX_STATUS = USART_RECEIVING; } } } } int main(void) { uint32_t distance; USART_Config(); // 使能接收中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); while (1) { // 发送获取距离命令 USART_SendString(USART1, "AT+DIST?\r\n"); // 等待接收到距离数据 while (USART_RX_STATUS == USART_RECEIVING); // 解析距离数据 sscanf((const char *)USART_RX_BUF, "+DIST:%ldmm", &distance); printf("Distance: %ldmm\r\n", distance); // 清空接收缓冲区和状态 USART_RX_STA = 0; USART_RX_STATUS = USART_RECEIVING; // 延时一段时间 Delay(1000); } } ``` 在上述代码中,使用USART1与GY-53-L1测距模块进行通信,通过发送"AT+DIST?"命令获取距离数据。当接收到一行数据时,会将数据存储到USART_RX_BUF缓冲区中,直到接收到换行符或缓冲区已满。然后从缓冲区中解析出距离数据,并打印到串口终端上。最后清空接收缓冲区和状态,并延时一段时间再次发送命令。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值