精华内容
下载资源
问答
  • GAN最新进展:8大技巧提高稳定

    千次阅读 2019-02-18 10:22:16
      【新智元导读】生成对抗网络GAN很强大,但也有很多造成GAN难以使用的缺陷。本文介绍了可以克服GAN训练缺点的一些解决方案,有助于提高GAN...GAN 本质上是由两个神经网络组成的系统——生成器 (Generator) 和...

    https://www.toutiao.com/a6656974166970860035/

     

    【新智元导读】生成对抗网络GAN很强大,但也有很多造成GAN难以使用的缺陷。本文介绍了可以克服GAN训练缺点的一些解决方案,有助于提高GAN性能。

    生成对抗网络 (GAN) 是一类功能强大的神经网络,具有广泛的应用前景。GAN 本质上是由两个神经网络组成的系统——生成器 (Generator)鉴别器 (Discriminator)——二者相互竞争。

     

    给定一组目标样本,生成器试图生成能够欺骗鉴别器的样本,使鉴别器认为这些样本是真实的。鉴别器试图从假的 (生成的) 样本中分辨出真实的 (目标) 样本。使用这种迭代训练方法,我们最终能得到一个非常擅长生成足以以假乱真的样本的生成器。

    GAN 有很多应用,因为它们可以学习模仿几乎所有类型的数据分布。通常,GAN 用于移除图像伪影、超分辨率、姿势转换,以及任何类型的图像翻译,例如下面这些:

    GAN最新进展:8大技巧提高稳定性

     

    使用 GAN 进行图像翻译 (Source: https://phillipi.github.io/pix2pix/)

    然而,由于其无常的稳定性,GAN 非常难以使用。不用说,许多研究人员已经提出了很好的解决方案来减轻 GAN 训练中涉及的一些问题。

    然而,这一领域的研究进展如此之快,以至于很难跟踪所有有趣的想法。本文列出了一些常用的使 GAN 训练稳定的技术。

    使用 GAN 的缺点

    GAN 难以使用的原因有很多,这里列出一些主要的原因。

    1、模式坍塌 (Mode collapse)

    自然数据分布是高度复杂且多模态的。也就是说,数据分布有很多 “峰值”(peaks) “模式”(modes)。每个 mode 表示相似数据样本的集中度,但与其他 mode 不同。

    在 mode collapse 期间,生成器生成属于一组有限模式集的样本。当生成器认为它可以通过锁定单个模式来欺骗鉴别器时,就会发生这种情况。也就是说,生成器仅从这种模式来生成样本。

    GAN最新进展:8大技巧提高稳定性

     

    顶部的图像表示没有发生 mode collapse 的 GAN 的输出。底部的图像表示发生了 mode collapse 的 GAN 的输出

    (Source: https://arxiv.org/pdf/1611.02163.pdf)

    鉴别器最终会发现这种模式下的样本是假的。但生成器仅仅是锁定到另一种模式。这个循环无限重复,从根本上限制了生成样本的多样性

    2、收敛 (Convergence)

    GAN 训练中一个常见的问题是 “我们应该在什么时候停止训练?”。由于鉴别器损失降低时,生成器损失增加 (反之亦然),我们不能根据损失函数的值来判断收敛性。如下图所示:

    GAN最新进展:8大技巧提高稳定性

     

    一个典型的 GAN 损失函数

    3. 质量

    与前一个问题一样,很难定量地判断生成器何时产生高质量的样品。在损失函数中加入额外的感知正则化可以在一定程度上缓解这种情况。

    4. 度量标准 (Metrics)

    GAN 目标函数可以解释生成器或鉴别器相对于其他方法的性能表现。然而,它并不代表输出的质量或多样性。因此,我们需要不同的度量标准。

    8大技巧提高GAN性能

    有很多技巧可以用来使 GAN 更加稳定或更加强大。这里只解释了相对较新的或较复杂的一些技术。

    1、替代损失函数 (Alternative Loss Functions)

    针对 GAN 的缺陷,最常用的一种修复方法是 Wasserstein GAN。它本质上用 Earth Mover distance (Wasserstein-1 distance 或 EM distance) 来替代传统 GAN 的 Jensen Shannon 散度。EM 距离的原始形式是难以处理的,因此我们使用它的 dual 形式。这要求鉴别器为 1-Lipschitz,它是通过削减鉴别器的权重来维持的。

    使用 Earth Mover distance 的优点是,即使真实的数据和生成的数据分布不相交,它也是连续的,这与 JS 散度或 KL 散度不同。同时,生成的图像质量与损失值之间存在相关性。缺点是,我们需要对每个生成器更新执行多个鉴别器更新。此外,作者认为,利用权重削减来确保 1-Lipschitz 约束是一种糟糕的方法。

    GAN最新进展:8大技巧提高稳定性

     

    即使分布不连续,earth mover distance(左)也是连续的,与 JS 散度 (右) 不同

    另一个解决方案是使用均方损失 (mean squared loss) 来替代对数损失。LSGAN 的作者认为,传统的 GAN 损失函数并没有提供太多的激励来将生成的数据分布 “拉” 到接近真实数据分布的位置。

    原始 GAN 损失函数中的 log loss 并不关心生成的数据与决策边界的距离 (决策边界将真实数据和虚假数据分开)。另一方面,LSGAN 对远离决策边界的生产样本实施乘法,本质上是将生成的数据分布 “” 得更接近真实的数据分布。LSGAN 用均方损失代替对数损失来实现这一点。

    2、Two Timescale Update Rule (TTUR)

    在这种方法中,我们对鉴别器和生成器使用不同的学习率。通常,生成器使用较慢的更新规则 (update rule),鉴别器使用较快的更新规则。使用这种方法,我们可以以 1:1 的比例执行生成器和识别器的更新,只需要修改学习率。SAGAN 实现正是使用了这种方法。

    3、梯度惩罚 (Gradient Penalty)

    在 Improved Training of WGANs 这篇论文中,作者声称 weight clipping 会导致优化问题。

    作者表示, weight clipping 迫使神经网络学习最优数据分布的 “更简单的近似”,从而导致较低质量的结果。他们还声称,如果没有正确设置 WGAN 超参数,那么 weight clipping 会导致梯度爆炸或梯度消失问题。

    作者在损失函数中引入了一个简单的 gradient penalty,从而缓解了上述问题。此外,与最初的 WGAN 实现一样,保留了 1-Lipschitz 连续性。

    GAN最新进展:8大技巧提高稳定性

     

    与 WGAN-GP 原始论文一样,添加了 gradient penalty 作为一个正则化器

    DRAGAN 的作者声称,当 GAN 所玩的游戏达到 “局部平衡状态” 时,就会发生 mode collapse。他们还声称,鉴别器围绕这些状态产生的梯度是“尖锐的”。当然,使用 gradient penalty 可以帮助我们避开这些状态,大大增强稳定性,减少模式崩溃。

    4、谱归一化 (Spectral Normalization)

    Spectral Normalization 是一种权重归一化技术,通常用于鉴别器上,以增强训练过程。这本质上保证了鉴别器是 K-Lipschitz 连续的。

    像 SAGAN 这样的一些实现,也在生成器上使用 spectral Normalization。该方法比梯度惩罚法计算效率更高。

    5、Unrolling 和 Packing

    防止 mode hopping 的一种方法是预测未来,并在更新参数时预测对手。Unrolled GAN 使生成器能够在鉴别器有机会响应之后欺骗鉴别器。

    防止 mode collapse 的另一种方法是在将属于同一类的多个样本传递给鉴别器之前 “打包” 它们,即 packing。这种方法被 PacGAN 采用,在 PacGAN 论文中,作者报告了 mode collapse 有适当减少。

    6、堆叠 GAN

    单个 GAN 可能不足以有效地处理任务。我们可以使用多个连续堆叠的 GAN,其中每个 GAN 可以解决问题中更简单的一部分。例如,FashionGAN 使用两个 GAN 来执行局部图像翻译。

    GAN最新进展:8大技巧提高稳定性

     

    FashionGAN 使用两个 GAN 进行局部图像翻译

    把这个概念发挥到极致,我们可以逐渐加大 GAN 所解决的问题的难度。例如, Progressive GAN (ProGAN) 可以生成高质量的高分辨率图像。

    7、Relativistic GAN

    传统的 GAN 测量生成的数据是真实数据的概率。 Relativistic GAN 测量生成的数据比真实数据 “更真实” 的概率。正如 RGAN 论文中提到的,我们可以使用适当的距离度量来度量这种“相对真实性”。

    GAN最新进展:8大技巧提高稳定性

     

    使用标准 GAN loss 时鉴别器的输出 (图 B)。图 C 表示输出曲线的实际样子。图 A 表示 JS 散度的最优解。

    作者还提到,鉴别器的输出在达到最优状态时应该收敛到 0.5。然而,传统的 GAN 训练算法强迫鉴别器对任何图像输出 “real”(即 1)。这在某种程度上阻止了鉴别器达到其最优值。 relativistic 方法也解决了这个问题,并取得了相当显著的效果,如下图所示:

    GAN最新进展:8大技巧提高稳定性

     

    经过 5000 次迭代后,标准 GAN(左) 和 relativistic GAN(右) 的输出

    8、自注意力机制

    Self Attention GANs 的作者表示,用于生成图像的卷积会查看局部传播的信息。也就是说,由于它们限制性的 receptive field,它们错过了全局性的关系。

    GAN最新进展:8大技巧提高稳定性

     

    将 attention map(在黄色框中计算) 添加到标准卷积操作中

    Self-Attention GAN 允许对图像生成任务进行注意力驱动的长期依赖建模。 Self-Attention 机制是对普通卷积运算的补充。全局信息 (远程依赖) 有助于生成更高质量的图像。网络可以选择忽略注意机制,也可以将其与正常卷积一起考虑。

     

    对红点标记的位置的 attention map 的可视化

    总结

    研究社区已经提出了许多解决方案和技巧来克服 GAN 训练的缺点。然而,由于新研究的数量庞大,很难跟踪所有重要的贡献。

    由于同样的原因,这篇文章中分享的细节并非详尽无疑,可能在不久的将来就会过时。尽管如此,还是希望本文能够成为人们寻找改进 GAN 性能的方法的一个指南。

    囿于篇幅,本文中的参考文献见原文:

    https://medium.com/beyondminds/advances-in-generative-adversarial-networks-7bad57028032

    展开全文
  • 嵌入式系统编程和调试技巧

    千次阅读 2014-09-17 21:47:54
    本文描述了嵌入式系统开发中编程调试的一些技巧,如何预防BUG出现,如何设置BUG陷阱,及时发现问题和定位问题,提高开发效率。

    嵌入式系统的开发,软件的运行稳定可靠是非常重要的。在芯片中,软件是没有质量的,但软件的质量可以决定一颗芯片的成败。芯片设计中,性能能否满足设计要求,除了硬件设计、软硬件配合的设计技巧,对于软件来说,编程的一些技术和技巧同样重要。

    本文讲述我在芯片固件开发过程中使用的一些编程调试技巧。针对在嵌入式系统开发中常见的问题,如实时系统下的同步问题,动态内存分配的内存泄漏问题,如何在编程阶段预防BUG出现,调试阶段如何及时发现问题和定位问题。总结下经验,目的是开发一个稳定运行的固件,提高开发效率,提高运行性能。

    一       编程调试技巧

    (一)      动态内存分配还是静态内存分配?

    嵌入式系统开发中,动态内存分配和静态内存分配各有利弊,动态内存分配灵活方便,但占用额外内存资源,调用时性能有损失,存在内存碎片问题。

    在无线芯片固件开发中,在两者的使用上主要考虑一下几点:

    • CPU性能
    • 可用内存大小
    • 需要使用内存分配的调用频率
    •  性能影响
    在实际设计中:
    • 考虑malloc函数调用的开销。所有的收发通路上对数据帧的处理、管理使用的数据结构都用静态内存分配的方式。目的是为了减少处理时间。
    • l站点管理,密钥管理,SDIO接口传递的外部命令,向上传送的SDIO事件管理采用动态内存分配的方式。这些调用和数据帧收发处理次数相比不是一个数量级,有的是偶尔调用。
    • 一次性分配,存在于软件整个生命周期的数据结构变量采用静态内存分配。

    (二)      使用ARM C库还是自己写一个?

    嵌入式系统开发中经常会使用到C库的一些函数,如malloc,free,memcpy,memset,printf,是自己写一个呢还是利用ARM开发工具提供的C库呢?

    我的习惯和建议是最好使用ARM的C库。优势就是

    • 使用方便,减少开发周期
    • ARM的C库性能会更好。

    我以memcpy为例,网上有篇分析arm memcpy汇编代码的文章,ARM公司写的代码为什么更优化,性能更好呢?它主要考虑了以下几点:

    • 源地址和目的地址的首地址的字节对齐问题
    •  拷贝字节长度
    • 末尾字节的对齐问题。
    • 尽量word拷贝
    • 尽量利用arm的批量拷贝汇编指令。

    所以我不会去另外写个memcpy函数。使用memcpy时只要注意,4-8个长的采用赋值方式效率会高些。或者不影响性能的情况下怎么用都无所谓。

    ARMC库有两种库:标准库和MicroC库。后者是非线程安全,在裸系统下使用。前者是线程安全的,可以在实时系统下使用。对malloc的使用用户需要实现一个保护和释放保护的函数,供C库使用。防止多线程调用malloc函数出现的同步问题。

    (三)      如何预防和发现内存泄漏

    使用动态内存分配,系统就可能出现内存泄漏,内存使用溢出,内存重复释放等问题,如果直接使用malloc和free,很难发现这样的BUG。在编程阶段,重定义malloc和free函数可以及时发现和定位这些问题。让程序去发现问题,而不是自己去找问题或者根本不知道有问题。

    重定义的malloc采用双向链表管理所有动态分配的内存。下面是管理内存使用的数据结构:

     


    每次内存分配分配如上大小的内存,包括三个部分,黄色部分为MEMORY_BLOCK数据结构,灰色部分为实际使用内存区,红色部分(4个字节)为尾部标记。

    MEMORY_BLOCK保存了双向链表,分配的文件名指针和文件行号,分配的长度和头部标记。

    这样在内存释放的时候就可以通过判断标记释放破坏来打印出错信息。重定义之后的malloc和free可以发现的内存问题和提示信息包括:

    • 检查尾部标记是否破坏,很可能本块内存使用溢出了,或者被其他地方非法写了。
    • 检查头部标记是否破坏,很可能被地址上方的其他内存破坏,或者被其他地方非法写了。
    • 在一块分配的内存第一次释放时,会把头部标记该为其他值,这样如果有重复释放的情况,检查会发现头部标记和分配内存时设置的不一致而发现问题。
    • 在系统退出时,应该所有内存都释放了。这时候检查内存管理链表,如果还有节点存在,说明有内存泄漏问题。
    • 对于未分配的内存,释放指针指向的内存区时,因在内存管理链表中找不到匹配的指针值,可以发现有非法释放的问题。
    • 出现内存释放问题时,可以打印调用分配函数的文件名和行号,分配的大小。如果MEMORY_BLOCK区破坏了,则可以查看该数据块的被填写的内容作为进一步判断问题的参考。

     

    重定义的malloc和free函数能够发现和定位绝大多数的内存使用的bug。可以杜绝内存泄漏问题。如果破坏了MEMORY_BLOCK区,则可以发现有问题,但定位需要自己再判断。

    (四)      注意大小端

    在嵌入式系统编程中,注意大小端问题是基本要求。

    • 注意访问的字段是大端还是小端格式的
    • 注意访问的字段在不同体系结构CPU(大小端不同)的访问问题。考虑代码的可移植性问题。
    • 慎重使用位域定义和操作,容易出现大小端问题。而且位域操作是需要较多指令才能实现。可以反汇编比较一下位域操作和位操作编译结果的不同。在有些嵌入式C语言规范中禁止使用位域也是这样的考虑。
    • 也不要有这样的想法:我的代码只会在小端CPU上运行。

     

    如果不想在小端CPU上执行的代码移植到大端CPU时,修改代码中大量读写操作。在刚开始写代码时注意这个问题可以避免以后吃大苦头。

    所以编写大小端访问的宏是必须的。代码如下:


    (五)      注意字节对齐问题

    因现在的嵌入式开发平台大部分是32位CPU,对51以及64位 CPU另外考虑。

    通常动态内存分配内存地址是word对齐的,编译器编译的结构体变量首地址也是word对齐的,对于结构体中变量定义,以及访问,对齐问题就需要编程者自己注意了。

    变量定义基本原则:

    • 对结构体中变量是half-word(2个字节长),必须是2的倍数边界对齐
    • 对结构体中是变量word型(4个字节长),必须是4的倍数边界对齐
    • 对结构体中变量是char型的(1个字节),可以任意边界对齐。如果是数组类型根据长度考虑。

    对于下面的数据结构(左边)定义,

                     

    虽然编译器编译时会进行字节填充,建议使用显式填充的方式定义(如上右数据结构)。

    对于变量读写操作变量,在变量定义时考虑对齐可以避免读写出现问题,比如代码中有可能跨word边界读写一个word。有些CPU体系结构会出现访问异常,有些CPU体系结构则读(或写)了一个错误值,但不会异常。对Intel的桌面平台的CPU,跨word边界读写不会有问题,因为CPU已经帮你解决这个问题,但影响是代码执行效率变差,这样的代码在windows平台是正常的,但到了嵌入式平台就会出现问题。所以根本的解决方式是在编程阶段注意这个问题。

    比如在无线网卡固件中,需要处理数据包中的字段,有些字段的起始地址是随机的,有可能是word对齐的,也有可能不是,访问这样的word变量时,加入__packed关键字。代码如下:

    u32data = *((u32 __packed *)da);

    这样编译器在编译时会编译为按字节读取再合并为word的汇编代码,不会出现读取数据问题。

    (六)      时刻关注同步访问问题

    在实时系统应用开发过程中,同步bug是经常碰到且比较难定位的bug。所以在编程阶段就进行考虑能避免后面调试时的痛苦。时刻关注同步访问问题,在编程过程中时刻自问下,这个变量的操作是否会出现同步问题,是否有多个线程进行写操作,释放时是否还有其他线程在用着呢?下面对开发过程中使用的保护技术进行下介绍。

    1          寄存器(变量)写的同步问题

    在嵌入式实时系统中,对寄存器或者内存中的变量的读写是很普遍的事情。以寄存器为例,如果是裸系统(不采用实时操作系统),只要把寄存器定义为volatile类型,就可以避免硬件会异步修改导致的软件编程编译之后的访问执行问题。

    在多任务的实时系统中,还需要注意多个任务会对寄存器进行写操作。这时候就需要保护操作。比如采用关中断,信号量或者互斥保护的办法。

    比如task1(低优先级)和task2(高优先级)都会读写MAC地址寄存器(两个word长的寄存器MAC_LOW_REG和MAC_HI_REG)。当task1刚写完MAC地址低四字节寄存器时,task2开始执行,然后向MAC地址寄存器写了不同的内容。task2执行完之后再切换回task1执行,task1继续写MAC地址寄存器(MAC_HI_REG)。这样的后果就是MAC地址寄存器中写人了非法的内容。

    在无线网卡固件中对寄存器操作的基本原则是:

    • 系统初始化读写的寄存器一般不需要保护,执行一遍就可以了。
    • 对任务(或线程)中对寄存器写操作采用信号量的保护方式,并对寄存器的访问按功能进行分类。把整个功能端进行保护,防止具体功能执行一半操作时被打断。同时尽量让功能端的代码不要太长。
    • 对只在某个线程中访问的寄存器可以不用保护,但原则上还是采用上面一条。
    • 对uart输出,因只是debug时调用,release的代码不包含这部分,所以不进行保护。实际使用也没发现影响系统。

     

    2          动态管理的结构体变量原子操作同步访问

    无线网卡固件会有一些动态分配和释放的结构体变量,比如站点管理,牵涉到多个线程的访问和释放。对这样的结构体同样需要保护。防止结构体释放之后,还有线程会对该结构体进行访问操作。对已释放的空间读写数据的bug在调试阶段比较难发现和定位,所以编程阶段就需要预防出现这样的问题。

    编程中保护的方法是采用原子操作的方式。具体的代码和操作步骤如下:

     

           在实现站点管理时,

    • 在加入一个站点时则调用kref_init(sta->kref),初始化原子变量为1
    • 需要访问这个站点是则调用kref_get(sta->kref),则原子变量为2.
    • 访问结束之后调用kref_put(sta->kref, release),则原子变量减为1.
    • 当释放时则再次调用kref_put(sta->kref, release), 原子变量减为0,调用release函数释放站点内存。
    • 对于多个线程的访问,因为都是采用kref_get,kref_put对,不会有问题。
    • 对于task2调用释放站点的函数,如果这时候有task1线程刚获取了kref_get,则task2释放站点的函数不会调用release函数,只有task1线程调用kref_put之后,才会真正释放站点内存。这样就实现了不会对已经释放内存的站点空间进行操作了。

     

    上面的代码参考了linux内核源代码,对于原子操作需要自己实现,ucos没有原子操作的函数,对于ARM7和ARM9可以采用开关中断的方式实现,对于Cortex-M3可以采用ARM的原子操作汇编指令实现。

     

    3          双向链表的同步访问

    网卡固件很多地方都采用了双向链表进行管理,比如站点管理,收发数据管理。对双向链表的操作包括加入一个节点,删除一个节点。除非该链表只在一个线程中使用,否则都采用信号量进行保护访问的方式。

    (七)      增加些打印统计信息

    1          输出统计信息辅助查找BUG。


    在项目的Debug版本中,利用实时系统创建的第一个任务start task周期性的打印这些统计信息,为了不影响功能和性能,间隔时间设为30秒。

    可以打印输出CPU的占用率,上下文切换次数,收发统计,动态内存分配次数的总的分配大小。

    在早期系统调试的时候因问题比较多,这些打印信息能很快帮助定位问题,比如receive frame count总是固定不变,而且数字为某个特定的值,基本可以判断接收停止了,而且为什么停止。

    而且通过接收的总次数和释放的总次数,以及接收之后的数据流向的个数,判断是否有未释放的,是那个模块处理的时候未释放。

    通过动态内存分配的打印信息可以判断是否有内存泄漏,系统需要的堆大概需要多大。

    ucos有CPU占用率的函数,直接调用就可以获取了,有些实时系统没有这样的函数,自己可以实现一个,原理就是实时系统有个系统时钟,每次触发,总的tick计数加1,系统空闲则,空闲(idle)任务会把自己的tick次数加1。(1-空闲任务tick数/总的tick数)就是cpu占用率。

    2          输出实时系统的任务相关信息。

    实时系统调试时,需要关注各个任务(线程)任务栈的使用情况。是否存在任务栈分配过大和过小的情况。过大浪费内存,过小会栈溢出。了解任务栈的使用情况,分配一个合适大小的栈。

    ucos有计数栈使用大小的函数,编译配置时一般不使能。 因为计数会影响性能。原理就是把某个任务栈初始化全0,任务栈使用之后,这块内存区使用的地方就变为非0的值了。因为是栈,所以计算时,从栈顶向下,计数为0的个数直到碰到非0的内存地址。栈大小减去剩下的0的字节数就是栈的使用大小了。

     

    (八)      按模块控制打印输出

    无线网卡固件在设计时分多个模块(线程,接口),每个模块使用专门的打印输出宏。并定义一个全局变量wl_debug_components用来控制那个模块需要打印输出。

    比如初始化设置为:

    #if DEBUG

    u32    wl_debug_components = COMP_INFO | COMP_TX | COMP_RX;

    #endif

    则代码运行是对调用COMP_INFO,COMP_TX, COMP_RX级别的打印语句输出打印信息。而且可以通过外部控制,如通过外部接口发送命令,修改wl_debug_components值,让程序输出打印和不打印某个模块的打印信息。

    打印输出的设计要求:

    • 按模块打印
    • 外部可以控制打印输出
    • debug版本把打印代码编译进去,release版本不编译进去。


    (九)      巧用开发环境和调试工具

    1.       ARM的semihost机制

    semihost机制是ARM的特点之一。可以利用JTAG在没有串口的情况下和调试环境的Command窗口收发相关信息,如写个菜单程序,在command窗口输出菜单,用户选择之后让程序做相应的操作。利用semihost好处是使用方便,在做一些功能性的测试时很有用,但printf的代码执行性能比用串口更差。

    2.       ARM调试器断点设置工具。

    Realview是个很强力的调试工具,不仅仅是设置断点,在代码执行到设置断点处停下来,还可以通过设置断点表达式,让CPU在指定条件下停下来。

    1)在对指定内存地址读写数据时触发断点。在调试过程中,经常会碰到某个区域被写了非法内容,想知道哪行代码在执行时进行了这样的操作吗?


    该断点触发的条件是对地址0x0E001800写操作的时候,CPU停止执行,这样就能看到代码执行到哪儿了。command还可以让CPU在停止时再执行某些命令,比如向控制台打印些消息啊,执行某个函数,等等。

    2)对某个函数执行n次,或者某行代码执行n次后停下。


    3)条件执行停止。可以设置断点,让全局变量setchar = 10时停止。这样就可以在设定某个指定条件是触发断点,让程序停止执行。

    (十)      利用CPU的特性来定位BUG

    1          利用ARM CPU的异常模式定位bug

    通常可以ARM CPU的指令异常:预取指异常,数据访问异常,未定义指令异常。比如执行一条非法指令(要么程序飞了,要么代码区破坏了)。非法向只读区写数据,预取指异常指向未获得正确访问权限的地方取指。一旦出现这样的问题,可以通过查看正常模式(user模式或者管理模式)的R14连接寄存器的值确定执行代码返回地址,结合编译器生成的.map函数映射文件,确定代码在执行什么函数,大概什么位置出现异常的。这种方法有很大的机会定位发生问题的地方。

    2          利用ARM9 CPU的MPU或者MMU结合上面一条定位BUG。

    ARM946E CPU是带有MPU的,编程时,可以把代码段和RO字段放在一个区,设置为只读属性,RW字段和ZI字段放在另外一个区,设置为读写属性。

    这样在代码中出现的向只读区写数据的问题都可以捕捉到。很多bug出现问题时会向0x0地址区写数据,比如使用设置初值为0的指针型变量,进行写操作时就会产生数据访问异常。

    (十一)       调试的软硬件配合

    • 串口是个很好的打印输出辅助调试设备。
    • 可以考虑IO口的输入输出,比如按钮,LED亮灯
    • 利用系统的定时器。对于实时系统,可以使用os的系统定时器,输出精度为1ms或者10ms。对于us精度要求的,可以直接使用CPU上的定时器,比如需要计算某段代码的执行时间,或者看看错误出现的时间,出现的间隔时间。
    • 可以配合示波器或者逻辑分析仪输出执行操作的时刻和间隔。

     

    二       结论

    对于一个嵌入式开发者来说,不断学习和经验积累,拓宽知识面对提高开发效率帮助很大。

    熟悉自己使用的工具,熟悉CPU的体系结构。仔细阅读开发工具的帮助手册,仔细阅读ARM公司免费的CPU体系结构文档,免费的ARM公司的编译工具文档。这些文档比书店卖的ARM开发的书有价值的多。

    阅读优秀的代码,积累编程技巧和调试手段。无论是内核开发,windows驱动开发,linux驱动开发还是嵌入式固件开发,很多技巧和技术是相通的。

    阅读芯片手册,包括芯片开发手册,积累软硬件配合的设计技巧,结合芯片代码了解其实现机制。

    调试时关注现象、细节,你的知识面可以帮助你从现象中很容易定位问题。

    以上是我嵌入式开发调试的一些经验和体会。
    展开全文
  • FPGA,verilog程序技巧之状态机与稳定性,高速

    千次阅读 多人点赞 2014-06-05 07:47:55
    原因FPGA编程的稳定性,在程序编写到一定程度后,就会出现,这里是要提示的地方。

     我的qq849886241  有疑问可以邮箱联系。

                关于FPGA的verilog语言的书,已经有很多很多了,甚至程序的写作标准也很完善了。本人FPGA入行两年,对很多的小问题,还有百度上很容易能想到,能看到的,我就不在描述,必定意义不大。对刚入门的FPGA的朋友,你们暂时还涉及不到稳定性问题。关于小白们,我能给你们的意见是,多百度,上面可以帮你解决,前2年遇到的所有问题。

               状态机的重要性,写过一两年程序的人都知道,不用多说了吧。直接上重点。

               第一个:输出信号填写问题,下面是我转载的一些能百度的到的东西。好像都比较正常。这里我还要强调的是,每个状态机的输出信号都需要全面。

    举例:

    always @ (posedge clk or negedge rst_n)              这里的状态机简单的描述,其实还有很多状态。

    ...//初始化                                              out3在s1  s2输出都是一样的,在状态跳转从s1跳到s2的

     case(next_state)                                                    时候out3会在s1处所存,所以就算在s2的地方不写一次out3 <= 1'b0 ;情况S1:                                                                         也是是输出0.对状态机要求高的话,需要这么写。

      out1 <= 1'b1;  

     out2 <= 1'b0;  

    out3 <= 1'b0;       //看这里    

    S2:

      out2 <= 1'b0;

     out2 <= 1'b1;

    out3 <= 1'b0 ;            //看这里    

    default:...    

    endcase

    end

                         第二个:程序输出结构。看程序应该能懂,不需要太多解释吧。

    举例:

    always @ (posedge clk or negedge rst_n)        

    case (next_state)                                                                                           

    S1:                                                                                                                      

    out1 <= 1'b1;                 //看这里                                          所有的不受if控制的输出都要写到if的外面。

     out2 <= 1'b0;                  

    if (x)                  

       out3 <= 1'b0;

    else

       out3 <=1'b1;

    S2:

      out2 <= 1'b0;       //看这里   

     out2 <= 1'b1;

    if (y)

       out3 <= 1'b0;

    else

       out3 <=1'b1;

     

    default:...    

    endcase

    end

                                        第三个。三段式(多段式)。简单描述就是将第三段的输出,在分为多段。

    举例:(我不知道我这么写例子是否恰当,只能表达一个意思吧)

    always @ (posedge clk or negedge rst_n)        

    case (next_state)                                                                                           

    S1:                                                                                                                      

    out1 <= 1'b1;            

     out2 <= 1'b0;                  

    S2:

      out2 <= 1'b0;      

     out2 <= 1'b1; 

    default:...    

    endcase

    end

    -------------------------------------------------------------------

    always @ (posedge clk or negedge rst_n)        

    case (next_state)                                                                                           

    S1:                                                                                                                                     

    if (x)                  

       out3 <= 1'b0;

    else

       out3 <=1'b1;

    S2:

    if (y)

       out3 <= 1'b0;

    else

       out3 <=1'b1;

     

    default:...    

    endcase

    end

                                             第四个。状态机的拆分,讲连续变化的状态机,从大的状态机里面拿出来。我只能这么说,没办法举例子了。这里涉及的编程思想也比较多了,没法描述但是要有这个思想。

                                              第五个。独热码好像有时候也不够稳定。你可以使用fifo来做状态缓存。当然这里只是理论概念,因为我还没写过,三段式,独热码,程序拆分后,还是不稳定的程序。但是如果以上内容你都做了,速度和稳定性还不够,你可以考虑的。主要的想法是这样的,fifo在多时钟域都可以良好的切换,就说明它的亚稳态现象很低,为什么状态机不稳定,就是对状态采样的时候,出现的问题。所以,它应该能做到更好的效果。

     

     

    微笑本人能力有限,但努力奉献我的知识,希望各位朋友可以快速成长。 

     

    -----------------------------------百度上截取--------------------------------------------------------------

    Verilog有限状态机三段式描述方法

    PART1

    1、好的状态机标准

    好的状态机的标准很多,最重要的几个方面如下:

    第一,状态机要安全,是指FSM不会进入死循环,特别是不会进入非预知的状态,而且由于某些扰动进入非设计状态,也能很快的恢复到正常的状态循环中来。这里面有两层含义:其一要求该FSM的综合实现结果无毛刺等异常扰动;其二要求FSM要完备,即使受到异常扰动进入非设计状态,也能很快恢复到正常状态。

    第二,状态机的设计要满足设计的面积和速度的要求。

    第三,状态机的设计要清晰易懂、易维护。


    2、状态机描述方法

    状态机描述时关键是要描述清楚几个状态机的要素,即如何进行状态转移每个状态的输出是什么状态转移的条件等。具体描述时方法各种各样,最常见的有三种描述方式:

    (1)一段式:整个状态机写到一个always模块里面,在该模块中既描述状态转移,又描述状态的输入和输出;

    (2)二段式:用两个always模块来描述状态机,其中一个always模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件描述状态转移规律以及输出

    (3)三段式:在两个always模块描述方法基础上,使用三个always模块,一个always模块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)


    一般而言,推荐的FSM  描述方法是后两种。这是因为:FSM和其他设计一样,最好使用同步时序方式设计,以提高设计的稳定性,消除毛刺。状态机实现后,一般来说,状态转移部分同步时序电路状态的转移条件的判断组合逻辑


    第二种描述方法同第一种描述方法相比,将同步时序和组合逻辑分别放到不同的always模块中实现,这样做的好处不仅仅是便于阅读、理解、维护,更重要的是利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。

    在第二种方式的描述中,描述当前状态的输出用组合逻辑实现,组合逻辑很容易产生毛刺,而且不利于约束,不利于综合器和布局布线器实现高性能的设计。

    第三种描述方式与第二种相比,关键在于根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而在不插入额外时钟节拍的前提下,实现了寄存器输出。


    PART2

    时序电路的状态是一个状态变量集合,这些状态变量在任意时刻的值都包含了为确定电路的未来行为而必需考虑的所有历史信息。

    状态机采用VerilogHDL语言编码,建议分为三个always段完成。


    三段式建模描述FSM的状态机输出时,只需指定case敏感表为次态寄存器,然后直接在每个次态的case分支中描述该状态的输出即可,不用考虑状态转移条件。

    三段式描述方法虽然代码结构复杂了一些,但是换来的优势是:使FSM做到了同步寄存器输出,消除了组合逻辑输出的不稳定与毛刺的隐患,而且更利于时序路径分组,一般来说在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。

    示列如下:

     

    //第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器

    always @ (posedge clk or negedge rst_n)   //异步复位

     if(!rst_n)

      current_state <= IDLE;

     else

      current_state <= next_state;  //注意,使用的是非阻塞赋值

     

    //第二个进程,组合逻辑always模块,描述状态转移条件判断

    always @ (current_state)       //电平触发

     begin

       next_state = x; //要初始化,使得系统复位后能进入正确的状态

       case(current_state)

       S1: if(...)

          next_state = S2;          //阻塞赋值

       ...

       endcase

    end

     

    //第三个进程,同步时序always模块,格式化描述次态寄存器输出

    always @ (posedge clk or negedge rst_n)

    ...//初始化

     case(next_state)

    S1:

      out1 <= 1'b1;               //注意是非阻塞逻辑

    S2:

      out2 <= 1'b1;

    default:...     //default的作用是免除综合工具综合出锁存器

    endcase

    end

     

     

    两段式有限状态机与三段式有限状态机的区别

    FSM将时序部分(状态转移部分)和组合部分(判断状态转移条件和产生输出)分开,写为两个always语句,即为两段式有限状态机。
    将组合部分中的判断状态转移条件和产生输入再分开写,则为三段式有限状态机。
    区别:
    二段式在组合逻辑特别复杂时适用,但要注意需在后面加一个触发器以消除组合逻辑对输出产生的毛刺。三段式没有这个问题,由于第三个always会生成触发器。
    设计时注意方面:
    1.编码原则

    binarygray-code适用于触发器资源较少,组合电路资源丰富的情况CPLD),对于FPGA,适用one-hot code。这样不但充分利用FPGA丰富的触发器资源,还因为只需比较一个bit,速度快,组合电路简单。

    2.FSM初始化问题:
    GSR(Gobal Set/Reset)只是在加电时清零所有的reg和片内ram,并不保证FSM能进入初始化状态,要利用GSR,方案是适用one-hot code with zero idle,即初始状态编码为全零。已可以适用异步复位rst
    3.FSM输出可以适用task
    4FSM中的case最好加上default,默认态可以设为初始态
    5.尤其注意
    第二段的always(组合部分,赋值用=)里面判断条件一定要包含所有情况!可以用else保证包含完全。
    6第二段always,组合逻辑电平要维持超过一个clock,仿真时注意。

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------

    展开全文
  • 本系列的第4部分着重讨论了环路稳定性的主要技巧与经验。 首先,我们将讨论45度相位及环路增益带宽准则,考察了在Aol曲线与1/β曲线以及环路增益曲线Aolβ中的极点与零点之间的互相转化关系。我们还将讨论用于环路...

    作者:Tim Green,TI公司

    本系列的第4部分着重讨论了环路稳定性的主要技巧与经验。

    首先,我们将讨论45度相位及环路增益带宽准则,考察了在Aol曲线与1/β曲线以及环路增益曲线Aolβ中的极点与零点之间的互相转化关系。我们还将讨论用于环路增益稳定性分析的频率“十倍频程准则”。这些十倍频程准则将被用于1/β、Aol及Aolβ曲线。我们将给出运放输入网络ZI与反馈网络ZF 的幅度“十倍频程准则”。我们将开发一种用于在1/β 曲线上绘制双反馈路径的技术,并将解释为何在使用双反馈路径时应该避免出现“BIG NOT”这种特殊情况。最后,我们将给出一种便于使用的实际稳定性测试方法。在本系列的第5 部分中,这些关键工具的综合使用使我们能够系统而方便地稳定一个带有复杂反馈电路的实际运放应用。

    环路增益带宽准则

    已确立的环路稳定性标准要求在fcl 处相移必须小于180 度,fcl 是环路增益降为零时的频率。在fcl 处的相移与整个180 度相移之间的差定义为相位余量。图4.0 详细给出了建议用于实际电路的经验,亦即在整个环路增益带宽(f≤fcl)中设计得到135 度的相移(对应于45 度的相位余量)。这是考虑到,在实际电路中存在着功率上升、下降及瞬态情况,在这些情况下,运放在Aol 曲线上的改变可能会导致瞬态振荡。而这种情况在功率运放电路中是特别不希望看到的。由于存在寄生电容与印制板布局寄生效应,因此这种经验还考虑在环路增益带宽中用额外的相位余量来考虑实际电路中的附加相移的。此外,当环路增益带宽中相位余量小于45 度时,即可能在闭环传输函数中导致不必要的尖峰。相位余量越低及越靠近fcl,则闭环尖峰就会越明显。


    图4.0:环路增益带宽准则

    图字(上下、左右):Aolβ(环路增益)相位曲线、-135°“相移”、频率 (Hz)、45°“相位余量”环路稳定性标准:在fcl 处相移< -180 度
    设计目的:在所有< fcl 的频率上,都有相移≤ -135 度(设计目的)
    原因:因为Aol(开环增益)并不总是“典型”,考虑到实际电路布局与器件的寄生效应,存在着功率上升、下降及暂态现象→这些是未定义的“典型” Aol。

    极点与零点转换技术

    图4.1 给出了环路增益曲线与Aol 曲线之间的关系,并包括了一条1/β 曲线。此关系使我们能够利用厂商提供的运放数据资料中的Aol 曲线来在图中绘制我们的反馈曲线1/β。从这两张图,我们可以方便地推断出环路增益曲线中的情况,从而更加方便地总结出,为得到良好的稳定性我们应该对反馈进行怎样的调整。

    考虑到环路增益曲线是一条“开环”曲线,而Aol 已经是一条开环曲线,因此Aol 曲线中的极点就是环路增益曲线中的极点,而Aol 曲线中的零点就是环路增益曲线中的零点。(总的趋势不变,故而极点即是极点,零点即是零点)

    1/β 曲线为小信号交流闭环增益曲线。如果我们想要断开环路来查看反馈网络的影响,则当分析网络时我们将看到一个倒数关系。用于记住从1/β 曲线到环路增益曲线转换的更简便方法就是,环路增益曲线是Aolβ 图,而闭环反馈曲线则是1/β 曲线。因此,既然β 是1/β 的倒数,那么1/β 曲线中的极点就成为环路增益曲线 (Aolβ) 中的零点,而1/β 曲线中的零点就成为环路增益曲线中的极点。


    图4.1:极点与零点转换技术

    图字:
    Aol&1/β 曲线、环路增益曲线 (Aolβ)
    从Aol&1/β 曲线来绘制Aolβ 曲线:
    Aol 曲线中的极点为Aolβ(环路增益)曲线中的极点
    Aol 曲线中的零点为Aolβ(环路增益)曲线中的零点
    1/β 曲线中的极点为Aolβ(环路增益)曲线中的零点
    1/β 曲线中的零点为Aolβ(环路增益)曲线中的极点
    (请记住:β 为1/β 的倒数)

    十倍频程准则

    图 4.2 详细描述了在环路增益曲线中的“十倍频程准则”。这些十倍频程准则将被用于1/β曲线,Aol曲线及Aolβ(环路增益)曲线,我们可以从Aol曲线及1/β曲线直接推导而来。对于本图所示的电路,Aol曲线在大约100kHz处包含了第二个极点fp2,这是因为存在容性负载CL及运放的RO,详细讨论将在本系列的第6 部分中给出。

    我们将建立一个满足我们环路增益带宽准则(即f≤ fcl时余量为45 度)的反馈网络。我们将利用我们对环路增益图(Aolβ) 的了解,使用1/β曲线及Aol曲线图来对反馈网络进行分析与综合。在环路增益曲线10Hz处给出了第一个极点fp1,这说明在10Hz处相移为 -45 度,在100Hz处相移为 -90 度。在1kHz、fz1、1/β曲线的零点处,我们在环路增益曲线上增加了一个极点,在1kHz处增加了另外 -45 度的相移。现在,在1kHz处,总的相移为 -135 度。

    但如果我们从fz1 开始继续增加频率,则在10kHz处相移将达到 -180 度!因此我们增加了fp3,作为1/β曲线上的极点,这在环路增益曲线上是10kHz处的零点(在10kHz处相移为 +45 度,在10kHz以上及以下斜率为+45度/decade)。这保证了1kHz处的相移为 -135 度,并使得从1kHz到10kHz的相位曲线都平坦地位于 -135 度(请记住极点和零点对于它们实际频率位置处的上十倍频程和下十倍频程频率都有影响)。fp2 在环路增益曲线100kHz处又增加了一个极点,这是因为fp2 是取自Aol曲线。在fp3 所在的10kHz 与fp2 所在的100kHz处,我们希望两者之间没有相移,因为fp3 是环路增益曲线的零点而fp2 则是环路增益曲线的极点。

    因此,如果我们保持极点与零点之间相隔十倍频程,则可避免它们之间的相移继续减少,因为它们各自对所在位置的上、下十倍频程都有影响。环路增益十倍频程准则最后的关键点是, fp3 应置于距fcl 一个十倍频程远处。这是考虑到,在我们可以达到一个余量稳定状态以前,Aol 会向低频偏移十倍频程。当遇上最坏情况时,就是Aol 随时间和温度发生了漂移,此时,许多IC 设计者都会将观测到的数字2 读成1(也就是说,1MHz 的统一增益带宽运放可能会从500kHz 偏移到2MHz)。我们推荐我们的十倍频程准则,因为它更容易记住并在波特图上可以方便地看出。额外的相位余量设计不会带来不便,但如果同时要求带宽、稳定性与性能话,那么2 变1 准则仍不失为一个好的选择。

    我们预计在环路增益离开100kHz以前,该电路的VOUT/VIN曲线都平的,之后它将跟随Aol曲线变化。


    图4.2:极点与零点转换技术

    图字:环路增益图解: 极点:fp1、fp2 及fz1;零点:fp3
    获得良好环路稳定性的经验:
    将fp3 置于离fz1 的1 个十倍频程以内
    fz1 处, fp1 和fz1 =-135°相移
    fp3≤ decade 将避免相移进一步降低
    将fp3 置于fcl 至少一个十倍程以下位置
    容许Aol 曲线左移一个十倍频程

    图4.3 给出了有关图4.2 所示电路的环路增益相位曲线的一阶人工分析预测。我们在1MHz 处增加了另一个极点fp4,来模拟真实世界中典型的双极点运放。(实际运放模型)

    个人小结:从上图可知相邻的零极点相位斜率是以10倍频为最小单位,其方向正好相反,这样综合起来的相位正好为一水平线段,为后续零极点相位裕量留下富裕。
    图4.3:一阶环路相位分析

    图字:单个极点和零点曲线、最终曲线

    为检验我们的一阶环路相位分析,我们用Tina SPICE 构建了我们的运放电路,如图4.4 所示。同时我们还用SPICE 环路增益测试来对Aol 曲线与1/β 曲线进行了测量。


    图4.4:Tina SPICE 电路:SPICE 环路增益测试

    图字:简单运放交流SPICE 模型

    图4.5 给出了Aol 和1/β 的Tina SPICE 仿真结果,并将其与我们一阶人工分析进行了仔细的相关比较。


    图4.5:Tina SPICE 电路:Aolβ 与1/β

    我们的Tina SPICE 仿真也被用来绘制环路增益与环路相位曲线。图4.6 给出了环路相位曲线,它是基于我们一阶人工分析得到的预测。


    图4.6:Tina SPICE 电路:环路增益与环路相位

    图字:环路增益、环路相位
    为检验我们的VOUT/VIN预测是否正确,我们将Tina SPICE电路修改成如图4.7 所示的电路并进行仿真。


    图4.7:Tina SPICE电路: VOUT/VIN

    图字:简单运放交流SPICE 模型

    图4.8 给出了VOUT/VIN的Tina SPICE仿真结果。我们看到VOUT/VIN传输函数从大约10kHz开始,有一个微小的上
    升。这是因为环路增益由于存在Rn-Cn网络而开始明显下降。但这与我们得到的一阶人工分析预测结果相差不大。一个值得再次提醒的关键点是,VOUT/VIN并非总是与1/β一致。(电感在spice彷真具有重要作用!)


    图4.8:Tina SPICE电路:VOUT/VIN 传输函数

    ZI 和 ZF 幅度十倍频程准则

    我们从本系列的第2 部分了解到ZI 和ZF 网络。图4.9 详细给出了ZI 输入网络中的幅度 “十倍频程准则”。如果我们标定Rp= RI/10(Rp 在数值上比RI 小“十倍”),则我们可以确定在高频情况下,当Cp阻抗短路时,Rp将把高频设置为RF/Rp。这样标定使我们能更容易地绘出1/β 曲线中起主要作用的一阶结果。幅度十倍频程准则的另一个优势是它迫使我们加入极点/零点对——fp 与fz,这样在其彼此一个十倍频程以内,以及因此在fp 与fz之间,相移将保持平坦。

    (文章的意思是电阻阻值都要满足10倍关系,这样迫使加入零极点对,且正好在十倍频内满足相位平坦要求。)

    图4.9:ZI 幅度十倍程准则
    图字:
    ZF:

    低频处1/β=RF/RI
    标定RF= RI/10
    这样在高频处:
    Cp=0
    Rp比 RF占优势 →1/β≈Rp/RI
    fp=1/(2⋅π ⋅Rn ⋅Cn )
    fz=1/(2⋅π ⋅RI ⋅Cn )
    (翻译的一塌糊涂,本人还要修改,翻译也要点专业精神!!!)


    图4.10 给出了ZF 反馈网络中的幅度“十倍频程准则”。如果我们标定Rp = RF/10(Rp 在数值上比RF 小“十倍”),则我们可以确定在高频情况下,当Cp 的阻抗短路时,Rp 将把高频设置为Rp/RI。这样标定使我们更容易绘出1/β 图中起主要作用的一阶结果。正如在输入网络ZI 中一样,幅度十倍频程准则的另一个优势是它迫使我们加入一个极点/零点对fp 和fz,这样在其彼此一个十倍频程以内,以及因此在fp 与fz 之间,相移将保持平坦。


    图4.10:ZF 幅度十倍频程准则

    图字:
    ZF:低频处1/β=RF/RI
    标定Rp = 1/10RF
    这样在高频处:
    Cn=0
    Rp 比 RF 占优势 →1/β≈Rp/RI
    fp=1/(2⋅π ⋅RF⋅Cp ),fz=1/(2⋅π ⋅Rp⋅Cp )

    双反馈路径

    随着本系列的不断深入,我们将看到,常常运用反馈电路来确保获得良好的运放稳定性,需要使用一个以上的反馈路径。为更方便地分析和综合此类多级反馈,我们将使用叠加原理。图4.11 定义了叠加原理。在此,我们将先单独分析每个影响,然后再将主要影响作为我们反馈的最终结果。


    图4.11:叠加原理

    摘自:Smith,Ralph J,“电路、器件与分析”,John Wiley&Sons 公司,1973 年第三版,纽约。

    图字:
    叠加原理:如果起因和影响线性相关,则同时起作用的几个起因造成的总的影响就等同于单个起因每次单独作用的影响之和。

    在图4.12 中,我们看到一个使用了两条反馈路径的运放电路。第一条反馈路径FB#1,位于运放的外部,经过Riso和CL后返回,并经过RF和RI回到运放的输入端。第二条反馈路径FB#2,位于运放的外部,经过CF然后返到运放的输入端。这里分别绘制了与这些反馈等效的1/β曲线。此推导的详细过程将在本系列的后续部分给出。当围绕运放使用一个以上反馈路径时,为运放提供最大反馈电压的反馈路径就成为主要的反馈路径。这意味着如果为每个反馈都绘制了1/β图,则在给定频率处,1/β最小的反馈就将在该点起主要作用。请记住,最小的1/β即最大的β,而由于β=VFB/VOUT,因此最大的β即表明反馈到运放输入端的电压最大。请记住一个简单的类比,即:如果两个人对着你的同一只耳朵讲话,那么哪个你听得更清楚一些呢——当然是讲话声较大的那个!所以运放将会“听”具有最大β或最小1/β的反馈路径。在FB#1 或 FB#2 的任何频率上,运放所看到的1/β曲线应该是较低的那个。


    图4.12:双反馈网络

    图字:
    类比:两个人同时对着你的耳朵讲话。你更能听见哪个呢?当然是讲话声大的那个!

    双反馈:有两条反馈路径在对运放“讲话”,它主要倾听反馈电压较大的路径 (β = VFB/VOUT),这意味着最小的1/β值!

    双反馈网络:
    - 采用叠加原理
    - 分析每个FB#1/β 并绘图、
    - 最小FB# 决定了1/β
    - 1/β=1/(β1-β2)。

    当围绕一个运放使用双反馈路径时,有一个极其重要的情况必须避免,即“BIG NOT”。如图4.13 所示,其中的运放电路导致反馈路径中产生BIG NOT 现象,该现象在1/β 曲线中可看到,图中1/β 斜率从+20db/decade 突然变成了-20dB/decade。这种改变意味着,在1/β 曲线上有中一个复共轭极点,这样相应地在环路增益曲线上即有一个复共轭零点。复零点与极点在其对应的频率上引起一个 +/-90 度的相移。此外,复零点/复极点的相位斜率,在其出现频率位置附近的一个狭窄频带内可从+/-90 度变化至+/-180 度。复零点/复极点的产生在闭环运放响应中可能会引起严重的增益尖峰,这是很不希望看到的情况,尤其在功率运放电路中。

                                (在多重反馈回路中,非常容易出现BIG NOT现象!)


    图4.13:双反馈与BIG NOT

    图字:警告:这对你的电路可能很危险!

    双反馈和BIG NOT:
    1/β 斜率从+20db/decade 变成-20dB/decade
    - 表明在1/β 曲线上有一个“复共轭极点”
    - 表明在Aolβ(环路增益)曲线上有一个“复共轭零点”
    - 在复零点/复极点的频率处有+/-90 度的相移
    - 在复零点/复极点所出现频率位置附近的一个狭窄频带内,相位频率可以从+/-90°/decade 变化至+/-180°,这取决于不同的阻尼系数
    - 复零点/复极点在闭环响应中可能会引起严重的增益尖峰

    图4.14 给出了不同阻尼系数情况下复共轭极点的幅度图。不论阻尼系数如何,极点都表现为双极点且斜率为-40dB/decade。但相位将给出不同的情况。


    图 4.14:复共轭极点幅度举例

    摘自:Dorf, Richard C.,“现代控制系统”,Addison-Wesley 出版公司,麻省雷丁,第三版,1981年。

    图4.15 给出了复共轭极点的相位图。很明显,由于阻尼系数不同,故相移相对于单纯双极点而言可能会有极大的不同。在双极点情况下,我们预计在该频率处的相移为 -90 度,斜率为-90 degree/decade(阻尼系数 =1)。


    图4.15:复共轭极点相位举例

    摘自:Dorf, Richard C.,“现代控制系统”,Addison-Wesley 出版公司,麻省雷丁,第三版,1981年。

    实际稳定性测试

    完成一阶人工分析后,再用SPICE 仿真来进行合理性检查,我们即能建立起自己的运放电路。如果有一种简便的方法可以判断实际相位余量是否就是我们分析得到的预测结果的话,那么这将带来许多便利。许多实际运放电路都是双极点、二阶及系统响应这些因素占优势。参见图4.16,一个典型的运放Aol 曲线在10Hz 至100Hz 范围内有一个低频极点,在其统一增益转换频率处、或者其后不远处有另一个高频极点。如果采用单纯的电阻反馈,我们会看到环路相位曲线将呈现出双极点系统效应。对于更复杂的运放电路来说,总的环路增益与环路相位曲线通常都是由双极点响应来决定的。二阶系统的闭环行为得到了很好的定义,并能为我们提供一种用于实际稳定性检查的强大技术。


    图4.16:运放电路的交流行为

    图字(上、下):大部分运放电路都采用众所周知的二阶系统响应行为来进行充分的分析,模拟及进行测试。
    (大部分运放datasheet都采用此模型)
    大部分运放都有两个极点占优势:
    Aol 曲线给出了一个低频极点fp1
    Aol 曲线还有一个高频极点fp2
    fp2 通常位于fcl 处以获得统一增益(单位增益)
    这就在统一增益处产生45 度的相位余量。

    图4.17 给出了详细的实际暂态稳定性测试。将一个小幅度方波馈入闭环运放电路中作为VIN源,在环路增益带宽中选择一个频率,但这个频率要足够高以便于触发示波器。1kHz对大部分应用来都说是一个不错的测试频率。调整VIN以使VOUT为200mVpp或更小。我们感兴趣的是电路的小信号交流行为,以找出交流稳定工作点。为此,我们不希望在输出上有较大的信号摆动,这可能也包含了一些大信号限制,例如摆动速率、输出电流限制或输出级电压饱和等。Voffset提供了一种机制,以在整个输出电压范围内上下移动输出电压以寻找在所有工作点条件下的交流稳定工作点。对许多电路(尤其是驱动容性负载的电路)来说,最差的稳定性情况是输出接近于零(对双电源运放应用)、且直流负载电流很小或完全没有的时候,因为这样会导致运放的开环小信号阻抗RO达到最大值。记下方波输出上的过冲与振铃量,并将其与图4.18 所示的二阶瞬态曲线进行对比。从与您的测量电路最匹配的曲线上记下相应的阻尼系数。在图4.19 中 的二阶阻尼系数比相位余量曲线的y轴上找出此相应的阻尼系数,X轴包含了二阶电路的相位余量。


    图4.17:实际瞬态稳定性测试

    图字:测试技巧:
    - 选择测试频率< - 调整VIN幅度以产生“小信号”交流输出方波
    - 通常最坏情况是当Voffset=0 时→ 最大运放RO值 (IOUT=0)
    - 任意改变Voffset来检验所有输出工作点,以找出稳定工作点
    - 令范围=交流耦合与扩展垂直范围刻度,以便找出VOUT小信号方波上的过冲、下冲及振铃量。


    图4.18:二阶瞬态曲线

    摘自:Dorf, Richard C.,“现代控制系统”,Addison-Wesley 出版公司,麻省雷丁,第三版,1981年。


    图4.19:二阶阻尼系数比相位余量

    摘自:Dorf, Richard C.,“现代控制系统”,Addison-Wesley 出版公司,麻省雷丁,第三版,1981年。

    参考文献:
    1、Frederiksen,Thomas M. ,“直观运放,从基础到应用”,修订版,McGraw-Hill 出版公司,纽约,1988
    2、Dorf,Richard C.,“现代控制系统”, Addison-Wesley 出版公司,麻省雷丁,第三版,1981 年。
    3、Smith,Ralph J.,“电路、器件与系统” ,John Wiley & Sons 出版公司,纽约,第三版,1973 年。

    展开全文
  • Win XP操作系统技巧

    千次阅读 2006-01-17 17:14:00
    一:系统使用二:安全模式的排除故障和解决顽症方法和案例.三:在使用解霸的过程中四:解开被锁注册表的四种方法五:加速你的RealOne Player 六:Windows病毒杀不死的原因分析及对策七:关闭不用的端口保安全八: ...
  • 线性时不变因果系统判断方法

    千次阅读 2021-03-26 09:52:32
    线性时不变因果电路的判断方法 在信号与系统的学习中 我们最常遇到的系统就是线性时不变因果系统的分析 下面我们来看一下如何判断线性 时不变 和因果的方法
  • 系统技巧和故障处理

    万次阅读 2006-08-18 11:34:00
    系统文件被破坏时,如Win2K下的KERNEL32.DLL,Win98 FONTS目录下面的字体等系统运行时基本的文件被破坏,系统在启动时会因此无法完成初始化而强迫重新启动。你可以做个试验,把WIN98目录下的字库“FONTS”改名试一...
  • 为什么这样说呢,在视觉系统中图像是核心,选择合适的光源能够呈现一幅好的图像,能够简化算法提高系统稳定性,一幅图像如果曝光过度则会隐藏很多重要的信息;出现阴影则会引起边缘误判;图像不均匀则会导致阈值选择...
  • 系统的分类是未来学习的基础,尤其是线性性以及时不变性,基于这两个性质的系统是《信号与系统》课程的研究重点。
  • 安全防护技巧:如何判断你的电脑是否含病毒2004年11月29日 16:39 enet硅谷动力 各种病毒时至今日也可算是百花齐放了,搞得人心惶惶,一旦发现自己的电脑有点异常就认定是病毒在作怪,到处找杀毒软件,一个不行,再...
  • Windows系统及应用技巧二十六篇

    万次阅读 2006-08-25 11:55:00
     四:如何防范恶意网站 五:win2000/xp忘记密码的方法 六:Windows XP 自带小工具 七:windows中有关网络的几命令 八:了解你的windows目录和系统文件 九:低级格式化的主要作用 十:封杀
  • 话说微技巧这个词也是我自己发明的,因为drawable这个东西相信大家天天都在使用,每个人都再熟悉不过了,之所以叫微技巧就是对于这个我们再熟悉不过的技术,可能还有一些你所不知道的细节,那今天我们就来一起探究...
  • 回答样本二:我受过系统的软件编程的训练,不需要进行大量的培训,而且我本人也对编程特别感兴趣。因此,我希望公司能根据我的情况和市场标准的水平,给我合理的薪水。 回答样本三:如果你必须自己说出具体数目,请...
  • 毕业设计答辩技巧&降重技巧

    万次阅读 多人点赞 2019-03-15 09:15:54
    大家答辩都是第一次,作为一个打交道多次的''老鸟'',从我的角度,给大家说一下常见的...问题2:你在进行数据库设计的时候,有什么技巧吗? 问题3:给我找到XX模块的代码,并讲解一下[XX流程是怎么实现的]? 问题...
  • 俄国学者李雅普诺夫提出的稳定性定理采用了状态向量来描述,适用于单变量,线性,非线性,定常,时变,多变量等系统,该方法称为...利用状态方程解的特性来判断系统稳定性。 1.1线性定常系统稳定性的特征值判据 ...
  • PCB技巧

    千次阅读 2011-08-23 17:30:04
    1.信号完整性(Signal Integrity):就是指电路系统中信号的质量,如果在要求的时间内,信号能不失真地从源端传送到接收端,我们就称该信号是完整的。 2.传输线(Transmission Line):由两个具有一定长度的导体...
  • 面试技巧:HR常问的70个问题回答技巧
  • 区块链:分布式系统核心技术

    万次阅读 2019-05-17 18:19:48
    万法皆空,因果不空。 随着摩尔定律碰到瓶颈,分布式架构越来越常见。...本章将介绍分布式系统领域的核心技术,包括一致性、共识的定义,基本的原理和常见算法,最后还介绍了评估分布式系统可靠性的指...
  • Android开发技巧——定制仿微信图片裁剪控件

    万次阅读 多人点赞 2016-03-08 16:57:50
    在Android中,裁剪图片的控件库还是挺多的,特别是github上比较流行的几个,都已经进化到比较稳定的阶段,但比较遗憾的是它们的裁剪过程是拖动或缩放裁剪框,于是只好自己再找,看有没有现成或半成品的轮子,可以...
  • 产品经理面试技巧

    万次阅读 多人点赞 2019-05-26 14:09:25
    本科信息管理与信息系统专业 2015年4月在阿里巴巴移动事业部实习 2015年11月offer选择了新美大产品岗 一、知识储备渠道 在校期间可以多尝试参加互联网创业、电子商务竞赛类的比赛,积累一些相关的项目经验,获得相关...
  • 注册表知识与技巧大全

    万次阅读 2011-12-18 15:53:38
    ********系统文件夹:********* 名称路径 含义 AppData C:\Windows\Application Data 应用程序 Cache C:\Windows\Temporary Internet Files 浏览器缓存 Cookies C:\Windows\Cookies Desktop Desktop 桌面...
  • Autocad技巧

    万次阅读 2013-04-24 16:30:08
    AutoCAD经典疑难解答与技巧 答:磨刀不误砍柴工。计算机绘图跟手工画图一样,也要做些必要的准备。如设置图层、线型、标注样式、目标捕捉、单位格式、图形界限等。很多重复性的工作则可以在模板图如ACAD.DWT...
  • Linux 实战技巧

    千次阅读 2018-05-31 18:55:19
    常用命令 adduser # 以创建 Apache Eagle 用户为例 $ adduser eagle $ passwd eagle # ur password for eagle user # 赋予用户可以 sudo 的权限 $ chmod u+w /etc/sudoers ... # 找到 `root ALL=(ALL) A...
  • 谈话的技巧

    千次阅读 2009-03-29 11:37:00
    与人谈话,不光有说的技巧,还要有听的技巧。不可能光说不听。要达到说与听的和谐。彼此愉悦。除了像上面各位同仁所说的各种话题。怎样使谈话受人欢迎,我摘录了下面的一段,关于谈话的技巧,望对大家都有帮助: ...
  • 稳定性 供应链管理是把正确数量的商品在正确的时间配送到正确的地点的一套管理方法,它控制和管理的各种”流”不包括(2) 系统方案设计包括总体设计与各部分的详细设计,( )属于总体设计。 实施商业智能的...
  • VC 技巧

    千次阅读 2006-03-12 17:03:00
    /*VC Studio 使用技巧大全 2.0版本 源代码和技术资料站点 http://www.vchelp.net/ gb http://www.csdn.net/ gb http://www.codeguru.com/ en http://www.codetools.com/ en http://www.dexv.com/ en msdn....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,983
精华内容 11,993
关键字:

判断稳定系统的技巧