2008年12月31日

减小DC/DC变换器中的接地反弹 — 一些接地要点

对接地分析的好文,转载于此,慢慢研读。减小DC/DC变换器中的接地反弹 — 一些接地要点

下载全文(PDF, 1,638 KB)

减小DC/DC变换器中的接地反弹 — 一些接地要点

By Jeff Barrow [jeff.barrow@analog.com]

电路接地1在电路原理图中看起来很简单;但是,电路的实际性能是由其印制电路板(PCB)布局决定的。而且,接地节点的分析很困难,特别是对于DC/DC变换器,例如降压型升压型变换器,这些电路的接地节点会聚快速变化的大电流。当接地节点移动时,系统性能会遭受影响并且该系统会辐射电磁干扰(EMI)。但是如果很好地理解“接地“引起的接地噪声的物理本质可提供一种减小接地噪声问题的直观认识。

接地反弹(Ground bounce)简称地弹会产生幅度为几伏的瞬态电压;最常见的是由磁通量变化引起的。传输电流的导线环路实际上构成了一个磁场,其磁场强度与电流成正比。磁通量与穿过环路面积和磁场强度乘 积成正比。

磁通量 ∝ 磁场强度 × 环路面积

更精确的表示是:

ΦB = BA cosφ

其中磁通量ΦB等于磁场强度B乘以穿过环路平面A和磁场方向与环路平面单位矢量夹角φ的余弦。

图1示出了磁通量与电流之间的关系。一个电压源驱动电流克服电阻沿导线环路流动。电流与环绕导线的磁通量相关联。为了将不同的物理量联系起来,可以考虑用你的右手握住导线(应用右手定则)。如果你的拇指指向电流的方向,那么你的其它手指将沿磁场磁力线方向环绕导线。因为那些磁力线穿过环路,所以形成了磁通量,在本例中磁通量方向为穿入页面。

Analog Devices :右手定则

图1. 右手定则

改变磁场强度或环路面积都会引起磁通量变化。当磁通量变化时,在导线中产生与磁通量变化率dΦB/d t成正比的电压。应该注意的是,当环路面积固定,电流变化;或者电流恒定,环路面积变化;或者两种情况同时变化——都会改变磁通量。

例如,假设图2中的开关突然断开。当电流停止流动时,磁通量消失,这会沿导线各处产生一个瞬态大电压。如果导线的一部分是一个接地返回引脚,那么以地电平为参考端的电压会产生一个尖峰,从而在任何使用该引脚为接地参考端的电路中都会产生错误信号。

Analog Devices :开启开关的作用

图2. 开启开关的作用

通常,PCB印制线电阻上的电压降不是接地反弹的主要来源。1盎司(oz)铜的电阻为500 微欧/方数(µΩ/⌈),因此1 A电流变化只能产生500 µV/⌈的反弹电压——问题只存在于采用细长印制线或菊花链式接地或精密电子电路。

寄生电容器的充电和放电为瞬态大电流返回到地提供了一条路径。由于电流变化引起的磁通量变化也引起接地反弹。

在DC/DC开关电源中减少接地反弹的最好方法就是控制磁通量变化——使电流环路面积和环路面积变化最小。

在某些情况下,例如图3所示,电流保持恒定,而开关切换引起环路面积变化,因此产生磁通量的变化。在开关状态1中,一个理想的电压源通过理想导线与一个理想电流源相连。电流在一个包含接地回路的环路中流动。

在开关状态2中,当开关改变位置时,同样的电流在不同的路径中流动。电流源为直流(DC),且并没有变化,但环路面子发生了变化。环路面积的变化意味着磁通量的变化,所以产生了电压。因为接地回路为变化环路的一部分,所以它会产生反弹电压。

Analog Devices

图 3

降压型变换器的接地反弹

为了讨论方便,将图3中的简单电路变换成与其类似的电路——图4中的降压型变换器。

Analog Devices

图4. 对于高频开关,大电容CVIN和大电感LBUCK可以看作一个电压源和电流源

在高频时,一个大电容器——例如降压型变换器输入电容器,CVIN——可以看作一个DC电压源。类似地,一个大电感器——例如降压型变换器输出电感器,LBUCK——也可以看作一个DC电流源。所做的这些近似有助于直观理解。

图5示出当开关在两个位置之间交替切换时磁通量如何变化。

Analog Devices: 开关对环路面积的影响

图5. 开关对环路面积的影响

大电感器LBUCK使输出电流大约保持恒定。类似地,大电容器CVIN保持电压大约等于VIN。由于输入引线电感两端的电压不变,所以输入电流也大约保持恒定。

尽管输入电流和输出电流基本不变,但当开关从位置1切换到位置2时,总环路面积会迅速变为原来的一半。环路面积的变化意味着磁通量的快速变化,从而沿着接地回路引起接地反弹。

实际上,降压型变换器由一对半导体开关构成,如图6所示。

虽然每个图中的复杂程度增加,但是通过磁通量变化引起接地反弹的分析方法仍然很简单和直观。

Analog Devices :采半导体开关对分析接地反弹的基本原理不变

图6. 采半导体开关对分析接地反弹的基本原理不变

事实上,磁通量的变化会沿着接地回路各处都产生电压,这就带来了一个有趣的问题:哪里是真正的地?因为接地反弹意味着,相对于称作的某个理想点(那一点需要定义),在接地返回印制线上产生一个反弹电压。

在电源稳压器电路中,真实的地应该连接在负载的低压端。毕竟,DC/DC变换器的目的是为负载提供稳定的电压和电流。电流回路上的其它所有点都不是真正的地,只是接地回路的一部份。

由于在负载的低压端接地并且环路面积的变化是接地反弹的原因,图7显示了如何精心地放置CVIN通过减小环路面积变化的比率降低接地反弹。

Analog Devices

图7. 精心放置CVIN可以大大减小接地反弹

电容器CVIN旁路PCB顶层的高端开关直接到达底层低端开关两端,因此减小了环路面积的变化,将其与接地回路隔离。当开关从一种状态切换到另一种状态时,从VIN的底部到负载的底部,无环路面积变化或开关电流变化。因此接地回路没有发生反弹。

Analog Devices :当开关从一种状态切换到另一种状态时不合理的布线会导致电流环路面积大幅变化

图8. 当开关从一种状态切换到另一种状态时不合理的布线会导致电流环路面积大幅变化

实际上,PCB布线本身决定了电路的性能。图8为图6中降压型变换器电路原理图的PCB布线图。当开关处于状态1所示的 位置,高端开关闭合,DC电流沿着外圈红色环路流动。当开关处于状态2所示的位置,低端开关闭合,DC电流沿着蓝色环路流动。注意由于环路面积变化引起磁 通量变化。因此产生电压和接地反弹。

为了清晰起见,在单层PCB上实现布线,但即使使用第二层整块接地平面也无法解决接地反弹问题。在展示改进布线图之前,图9给出了一个简单例子说明地平面无法解决问题。

Analog Devices :整体地平面并不总是一个好方法

图9. 整体地平面并不总是一个好方法

这里,我们采用双层PCB以便在与顶层电源线垂直处附加一个旁路电容。在左边的例子中,地平面是整体的并且未切割。顶层印制线电流通过电容器流过,穿过过孔,到达地平面。

因为交流(AC)电总是沿着最小阻抗路径流动,接地返回电流绕着其路径拐角返回电源。所以当电流的幅度或频率发生变化时,电流的磁场及其环路面积发生变化,从而改变磁通量。电流沿最小阻抗路径流动的规律意味着,即使采用整体地平面也会发生接地反弹——与其导通性无关。

在右边的例子中,一个经过合理规划切割的地平面会限制返回电流以使环路面积最小,从而大大减小接地反弹。在切割返回线路内产生的任何剩余接地反弹电压与通用地平面隔离。

图10中的PCB布线利用图9中示出的原理减小了接地反弹。采用双层PCB板以便将输入电容器和两个开关安排在地平面的孤岛上。

这种布线不必最好,但它工作很好,而且能够说明关键问题。应该注意红色电流(状态1)和蓝色电流(状态2)包围的环路面 积很大,但两个环路面积之差很小。环路面积变换很小意味着磁通量的变化小——即接地反弹小。(然而,一般情况下,也要保证环路面积小——图10只是为了说 明AC电流路径匹配的重要性。)

另外,在磁场和环路面积发生变化的接地回路孤岛内,沿着任何接地回路引起的接地反弹都受接地切割限制。

此外,可能第一眼看上去,输入电容器CVIN好像没有位于图7中所示的顶层高端开关和低层低端开关之间,但进一步观察才会发现是这样。尽管物理邻近可以很好,但真正起作用的是通过最小化环路面积实现的电子接近。

合理的降压型变换器布线可以使状态1和状态2之间的环路面积变化很小

图10. 合理的降压型变换器布线可以使状态1和状态2之间的环路面积变化很小

升压型变换器中的接地反弹

升压型变换器实际上是降压型变换器的反射,因此——如图11所示——它是输出电容器,输出电容器必须放在顶层高端开关和底层低端开关底端之间以使环路面积变化最小。

Analog Devices

图11. 按照降压型变换器将CVIN放在关键位置相同的方法,升压型变换器将CVOUT放在关键位置。
a)不合理设计,b)合理设计。

小结

接地反弹电压主要是由于磁通量变化引起的。在DC/DC开关电源中,磁通量变化是由于在不同的电流环路面积之间高速切换 DC电流引起的。但是精心放置降压型变换器的输入电容器和升压型变换器的输出电容器并且合理切割接地平面可以隔离接地反弹。然而,重要的是当切割地平面时 必须谨慎以避免增加电路中其它返回电流的环路面积。

另外,一个合理的布线应该将真正的地放在连接负载的底层,不会引起环路面积的变化或电流的变化。任何其它与导通相关的点都可以称为“地”,但它只是沿着返回路径的一点而已。

其它用于接地分析的有用概念

如果你牢记下述基本概念,你就会清楚地知道什么情况会产生接地反弹,什么情况不会产生接地反弹。图12示出了相互垂直的两个导体不会遭受磁场的互相影响。

相互垂直的两个导体不会遭受磁场的互相影响

图12. 相互垂直的两个导体不会遭受磁场的互相影响

沿着相同方向传输相等电流的两条平行导线周围产生的磁力线在两条导线之间处会相互抵消,所以两条导线总储存能量要比单独一条导线储存的能量少。因此,PCB宽印制线的电感要比窄印制线小。

电流沿着相同方向流动的两条平行导线

图13. 电流沿着相同方向流动的两条平行导线

沿着相反方向传输相等电流的两条平行导线周围产生的磁力线在两条导线的外部相互抵消,而在两条导线之间处增强。如果内部环路面积缩小,那么总磁通量,所以电感也随之变小。该现象可以解释为何AC地平面的返回电流总是沿顶层印制线导线下方流动。

电流沿着相反方向流动的两条平行导线

图14. 电流沿着相反方向流动的两条平行导线

图15示出了为何拐角增加电感。一条直导线只能看到它自己的磁场,但是在拐角处,还能看到垂直导线的磁场。因此,拐角储存了更多的磁场能量,其电感要大于直导线。

为何拐角增加电感

图15. 为何拐角增加电感

图16示出了在传输流的导线下面切割接地平面,由于转移回路电流可增加环路面积,从而增大环路尺寸并且助长接地反弹。

返回电流沿着最小阻抗路径流动

图16. 返回电流沿着最小阻抗路径流动

元件方向的作用,如图17所示。

元件方向的影响

图17. 元件方向的影响

总结

接地反弹一直是一个潜在的问题。对于监视器或电视,它意味着图像有噪声;对于音频设备则意味着噪声本底。在数字系统系统中,接地反弹可能会导致计算错误——甚至是系统崩溃。

对于预测接地反弹幅度来说,仔细估计寄生元素和细致的仿真是有效的方法。但对指导电路设计的直觉,理解背后的物理原理是很必要的。

首先,设计PCB时,应该将负载的低压端设置为真正的地。

然后,用电流源和电压源容替大电感器和电容器以简化电路动态特性。观察每种开关组合下的电流环路。应该使环路重叠;如果无法做到重叠,应该精心地在地平面上切割出一个小岛以确保只有DC流入和流出孤岛开口。

在大多数情况下,经过这些努力可以获得可以接受的接地性能。如果还是不能,应该首先考虑地平面的电阻,然后考虑所有开关和进入返回路径的寄生电容器两端流过的位移电流。

无论什么电路,基本接地原理都是相同的——应该使磁通量的变化最小或者对它隔离。

尾注

1Analog Dialogue杂志已经发表了许多关于“接地”问题的文章。这些文章可以在我们的综合在线存档文件中找到。Paul Brokaw和本文作 者合作撰写的一篇文章,见23-3 (1989) pp. 7-9。其中包括与接地和噪 声相关的早期参考文献索引。相关资料见11-2 (1977) pp. 10-15; 25-2(1991) pp. 24-25; 26-2 (1992) p. 27 (包含一系列很好的参考文献); 30-2 (1996) p. 11 (包括EMC/EMI/ESD方面的参考文献);39-3 (2005) pp. 3-8。研讨会教材《High Speed System Applications(高速系统应 用)》,Walt Kester和Hank Zumbahlen编著,ADI公司出版 (2006),书 中有大量章节介绍PCB布线和设计工具(pp. 4.1-4.90)。其它相关文章 还有“Reducing ground bounce in dc/dc-converter applications(减小 DC/DC变换器应用中的接地反弹)”,Jeff Barrow,EDN, 7/6/2006。

2008年12月28日

PCB板加工参数

今天去赛格电子市场,了解了一下4层PCB板加工的情况:
  • 最小线宽:4mil/0.1mm
  • 最小安全间距:4mil/0.1mm (线宽不能小于安全间距)
  • 最小过孔:8mil/0.2mm
  • 加工要求过孔外径不能小于0.15mm,如果外径减小则需要板厚加大

2008年12月22日

miniBfin最小系统板硬件设计完成啦!

BF532最小系统:
  • BF532
  • 32M SDRAM
  • 8M SFlash
  • UART
  • JTAG
  • GPIO Interface
  • Power
先睹为快!

2008年11月26日

BF532芯片内调试UART程序

今天写了一段UART串口消息输出调试代码,用于加载到芯片L1 RAM中运行测试UART的连接情况,成功输出信息:Hello Bfincn
代码比较简单,大家看看就明白了。

#include "bin2ldr.h"

#define hi(x) (x >> 16)
#define lo(x) (x & 0xffff)

/* UART Controller (0xFFC00400 - 0xFFC004FF) */
/* Transmit Holding register */
#define UART_THR 0xFFC00400
/* Receive Buffer register */
#define UART_RBR 0xFFC00400
/* Divisor Latch (Low-Byte) */
#define UART_DLL 0xFFC00400
/* Interrupt Enable Register */
#define UART_IER 0xFFC00404
/* Divisor Latch (High-Byte) */
#define UART_DLH 0xFFC00404
/* Interrupt Identification Register */
#define UART_IIR 0xFFC00408
/* Line Control Register */
#define UART_LCR 0xFFC0040C
/* Modem Control Register */
#define UART_MCR 0xFFC00410
/* Line Status Register */
#define UART_LSR 0xFFC00414
/* SCR Scratch Register */
#define UART_SCR 0xFFC0041C
/* Global Control Register */
#define UART_GCTL 0xFFC00424


/* Initialise UART */
p0.h = hi(UART_LCR);
p0.l = lo(UART_LCR);

/* 8-bit word; 1 stop bit; No parity */
r0 = 0x83(Z);
w[p0] = r0.l; /* To enable DLL writes */
ssync;

p0.h = hi(UART_DLL);
p0.l = lo(UART_DLL);

/* SCLK = 133MHz, BaudRate=115200
BaudRate = SCLK /(16 * Divisor) */
r0 = 0x48(Z);
w[p0] = r0.l;
ssync;

p0.h = hi(UART_DLH);
p0.l = lo(UART_DLH);
r0 = 0x00(Z);
w[p0] = r0.l;
ssync;

p0.h = hi(UART_GCTL);
p0.l = lo(UART_GCTL);
r0 = 0x1(Z);
w[p0] = r0.l; /* To enable UART clock */
ssync;

/* Begin to process rx/tx data */
p0.h = hi(UART_LCR);
p0.l = lo(UART_LCR);

/* 8-bit word; 1 stop bit; No parity */
r0 = 0x03(Z);
/* To enable access THR/PBR */
w[p0] = r0.l;
ssync;

/* Write 'Hello Bfincn' to Console */
p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x48(Z); /* H */
w[p0] = r0.l;
ssync;

ww1:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww1;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x65(Z); /* e */
w[p0] = r0.l;
ssync;

ww2:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww2;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x6c(Z); /* l */
w[p0] = r0.l;
ssync;

ww3:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww3;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x6c(Z); /* l */
w[p0] = r0.l;
ssync;

ww4:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww4;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x6f(Z); /* l */
w[p0] = r0.l;
ssync;

ww5:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww5;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x20(Z); /* space */
w[p0] = r0.l;
ssync;

ww6:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww6;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x42(Z); /* B */
w[p0] = r0.l;
ssync;

ww7:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww7;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x66(Z); /* f */
w[p0] = r0.l;
ssync;

ww8:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww8;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x69(Z); /* i */
w[p0] = r0.l;
ssync;

ww9:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww9;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x6e(Z); /* n */
w[p0] = r0.l;
ssync;

ww10:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww10;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x63(Z); /* c */
w[p0] = r0.l;
ssync;

ww11:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump ww11;

p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
r0 = 0x6e(Z); /* n */
w[p0] = r0.l;
ssync;

ww12:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,0);
if !cc jump ww12;

/* read from buffer */
p0.h = hi(UART_RBR);
p0.l = lo(UART_RBR);
r1 = w[p0](z);

/* send buffer is empty or not */
wait:
p0.h = hi(UART_LSR);
p0.l = lo(UART_LSR);
r0 = w[p0](z);
cc = bittst(r0,5);
if !cc jump wait;

/* write back to console */
p0.h = hi(UART_THR);
p0.l = lo(UART_THR);
w[p0] = r1.l;
ssync;

/* if user enter the char 'q' then exit */
r1 = 0x72(z);
cc = r0 == r1; /* q */
if !cc jump ww12;

p0.l = (APP_ENTRY & 0xFFFF);
p0.h = (APP_ENTRY >> 16);
jump (p0);

2008年11月25日

看图学布线










2008年11月23日

掌握高级处理器特性可提高编码效率

掌握高级处理器特性可提高编码效率
数字信号处理器(DSP)在性能、外设、功耗和价格上已经结合得非常好了,许多系统工程师希望利用DSP的优势,取代传统设计方案中使用的处理器,但一个 潜在难题是设计工程师已经为他们的应用开发了大量C和C++代码。很明显,工程师都愿意在DSP平台上利用现有的高级代码,同时利用DSP的体系结构特性 以获得更好的性能。

  HLL与汇编语言

  当开发基于DSP的软件时,必须要做的一项工作就是确定使用哪一种程序设计方法学,通常是在汇编语言和高级语言(HLL)(例如C或C++语言)之间进行选择。

  C和C++的优点包括模块性、便携性以及可重复利用性。

  传统的汇编语言由于其语法和缩写难以理解和使用,长期以来不被人们所看好。目前的“代数语法”体系结构有了很大改进。表1是使用传统风格和使用代数格式的典型DSP指令实例,很显然后者的结构更加直观。在所提供的实例中,r寄存器是数据寄存器,p寄存器是指针寄存器。

  用汇编语言编程困难的一个原因是由于其数据流集中在DSP实际寄存器组、计算单元和存储器之间。用C或C++语言编程,这种操作通常通过使用变量和函数,或过程调用出现在更加抽象的处理


等级之间,从而使得代码更容易跟随。

  为提高DSP执行效率,工具开发商会使用汇编语言对重要的数据密集代码模块进行优化。HLL编译优化转换可以很好地完成该项工作,而且对DSP 数据流和计算的直接控制能力是极为出色的。这就是为什么设计工程师通常结合使用C/C++和汇编语言。HLL适合于控制和基本的数据操作,而汇编语言适合 于高效的数字计算。

  适合高效编程的体系结构的特性

  为了使汇编语言程序员能够有效地完成工作,需要了解处理器的结构类型,以便能够区分不适合高速数字计算的那些DSP处理器。这些适合高效编程的体系结构结构特性包括:

  ● 专用寻址模式

  ● 硬件环路结构

  ● 高速缓冲存储器

  ● 每周期多次操作

  ● 互锁流水线

  ● 灵活的数据寄存器文挡

  专用寻址模式

  允许处理器在单周期内访问多个数据字需要灵活的地址产生方式。除了需要更大的以DSP为中心的16bit和32bit边界的访问尺寸外,还需要 字节寻址以达到最有效的处理。这是非常重要的,因为一些普通应用(例如许多基于视频的系统)都是按照8bit数据操作。当处理器访问限制在单一边界内时, 处理器可能需要额外的周期来掩蔽掉相关的位。

  另外一种有利的寻址能力是“循环缓冲”。该特性必须直接由处理器支持,无须专门的软件管理开销。循环缓冲允许程序员定义存储器中的缓冲器,并且 自动跨越它们。一旦缓冲器设置好,则无须专门的软件交互操作数据。地址发生器处理非同式跨幅,更重要的是可以处理图1所示的“环绕式”特性。如果没有这种 自动地址产生功能,程序员必须手动跟踪缓冲器,从而浪费了宝贵的处理周期。

图1 环绕式缓冲的例子

  在此例中,基地址和起始索引地址=0x0;索引地址寄存器I0指向地址0x0;缓冲器长度L=44(11个数据元素×4字节/元素);修改寄存器M0=16(4个数据元素×4字节/元素)

  实例代码:

  R0 = [I0++M0]; //R0 = 1,I0在代码执行后指向0x10

  R1 = [I0++M0]; //R1 = 5,I0在代码执行后指向0x20

  R2 = [I0++M0]; //R2 = 9,I0在代码执行后指向0x04

  R3 = [I0++M0]; //R3 = 2,I0在代码执行后指向0x14

  R4 = [I0++M0]; //R4 = 6,I0在代码执行后指向0x24

  用于高效信号处理运算(例如快速傅立叶变换(FFT)和离散余弦变换(DCT))的一种重要寻址模式是比特翻转。顾名思义,“比特翻转”就是将 二进制地址中的比特翻转,也就是说将权值最小的比特与权值最大的比特交换位置。由基为2的蝶形所要求的数据顺序是“已翻转比特”的顺序,因此比特翻转索引 用来组合FFT级。可以计算软件中的这些比特翻转索引,但是这样做的效率非常低。图2所示是比特翻转地址流实例。

图2 硬件比特翻转机理

  实例代码:

  LSETUP(起始, 终止)LC0=P0; //循环数P0=8

  起始:R0 = [I0] || I0 += M0(BREV); //I0指向输入缓冲器,在比特翻转过程中自动增加

  终止:[I2++] = R0; ; //I2指向比特翻转缓冲器

硬件循环结构

  循环在通信处理算法中是一项很重要的特性。有两个与循环有关的关键特性能够改进多种算法的性能。第一个特性称作“零开销硬件循环”。随着寻址能 力的提高,循环结构可以在硬件中实现。此外,当该项功能用软件实现时,相关的开销可减小到实时处理预算。零开销循环允许程序员通过设置计数值并且定义循环 边界初始化循环。处理器将继续执行循环直到计数结束。

  零开销循环是大多数处理器必不可少的一部分,但“硬件循环缓冲器”实际上可以提高循环结构的性能。它们用作循环中所执行指令的一种高速缓冲存储 器。例如,在第一次执行完一个循环之后,可将该指令保存在循环缓冲器中,从而无须在每一次循环都反复重取相同指令。通过将循环指令保存在能够在单周期内访 问的缓冲器中,能够节省大量的周期数。该特性不需要程序员进行额外的设置,但是需要知道循环缓冲器的尺寸以合理地选择循环大小。

  高速缓冲存储器

  通常典型的DSP具有少量的快速、内置存储器。MCU通常可以访问大量的外部存储器。分层存储器体系结构将这两种方案的优点结合在一起,从而可提供几种等级具有不


同性能的存储器。对于需要最高性能应用,可以在单个核心时钟周期内访问内置SRAM。对于具有大代码尺寸的系统,可提供大量、较长等待延迟的片内和片外存储器。

  这种分层存储器体系结构本身仅仅是发挥一定的作用,由于现在的高性能处理器常常运行在较低的时钟频率下,因此大的应用程序只能装在较慢的外部存 储器中。此外,程序员被迫手动将关键代码移入和移出内部SRAM。但是,通过将数据和指令高速缓冲存储器加到该体系结构中后,外部存储器更易于管理,高速 缓冲存储器可以减少将指令和数据移入处理器内核的手工操作。由于不需要考虑进入内核的数据和指令流管理,可以大大简化编程模式。

  指令高速缓存通常采用了某种类型的最近最少使用(LRU)算法,从而确保更常用的指令代替较少使用的指令。将一些内置数据存储器配置为高速缓存 和部分SRAM的能力可以优化性能。直接存储器访问(DMA)控制器能够直接控制内核,同时当需要表中数据时将其读入数据高速缓存。一旦高速缓存允许并且 DMA控制器配置完毕,则程序员即可集中精力于内核算法的开发。

  每周期多次操作

  通常以每秒执行多少百万条指令(MIPS)来衡量处理器。曾经被保留用在高成本并行处理器中的多发布指令目前也可用在低成本、定点处理器中。除 了在每个核心处理器周期内完成多条ALU或MAC操作外,在相同周期内还可完成额外的数据处理和数据存储。存储器通常划分为子若干个存储器组,这些存储器 组可以被内核双向访问并且被DMA控制器随机访问。鉴于上述的基于硬件的寻址算法的分解方法,很明显其可以在单个周期内完成许多操作。

  图3示出多操作指令的一个实例。如图3所示,在一个周期内除了完成两条独立的MAC操作外,在相同的处理器时钟周期内还完成了数据读取和数据存储。

图3 Blackfin多发布指令在单周期内完成几次操作

  互锁流水线

  随着处理器速度的增加,从整个电路级来看处理流水线必定会变得更深。然而,有些处理器具有“互锁”流水线。这意味着当完成汇编语言编程时,程序员不必手动调度或跟踪通过流水线的数据和指令。处理器会自动处理这些时序的事情。

  灵活的数据寄存器文档

  最后,另外一个补充特性是通用数据寄存器集。在传统的定点DSP中,字长通常是固定的。然而,具有能够用作一个32bit(例如R0)或两个 16bit(例如分别用于低8bit和高8bit的R0.L和R0.H)的数据寄存器是非常有利的。在双MAC系统中,这允许在单周期内操作四个 16bit的数据。

  内积

  内积或者标量积在度量两个向量的正交性时是很有效的操作。大多数C语言程序员应该熟悉以下的内积操作:

  short dot(short a[], short b[], int size) {

   int i;

   int output = 0;

   for(i=0; i<>

   output += (a[i] * b[i]);

   }

  return output;

  下面是Blackfin处理器汇编代码的主要部分:

  //P0=loop count, I0 & P1 are address registers

  A1 = A0 = 0; // A0 & A1 are accumulators

  LSETUP (loop1,loop1) LC0 = P0 ;// Setup hardware loop starting at label loop1:

  loop1: A1 +=R1.H*R0.H, A0+=R1.L*R0.L||R1=[P1++]||R0=[I0++];

下面几点说明了简化这种紧凑编码的DSP体系结构特性。

  硬件循环缓冲器和循环计数器在每次迭代的末端不需要跳转指令。由于内积是乘积总和,因此可在一次循环中完成。该汇编程序所示是LSETUP指令,它是执行循环所需的唯一指令。

  多发布指令允许在相同的周期内执行多条指令和两次数据访问。在每一次迭代时,必须先读取a[i]和b[i]值,然后相乘,最后写回到可变输出的运行总和中。在许多MCU平台上,这实际上等于四条指令。汇编代码的最后一行示出在一个周期内可执行的所有操作。

  并行ALU操作允许同时执行两条16bit指令。汇编代码示出在每次迭代中使用的两个累加器单元(A0和A1),这将迭代次数减少了50%,从而将原来的执行时间减少了一半。

  FIR算法

  有限脉冲响应(FIR)滤波器是一种等价于卷积操作很常见的滤波器结构。A通过C操作看起来非常类似于内积。

  //将信号取样到循环缓冲器中

  x[cur] = sampling_function();

  cur = (cur+1)%TAPS; // 在循环中增加cur指针

  //完成乘加

  y = 0;

  for (k=0; k<>

   y += h[k] * x[(cur+k)%TAPS];

  }

  使用汇编语言编写的FIR内核格式有些类似于内积。在这个特定的例子中,取样值存储在R0寄存器中,同时系数存储在R1寄存器中。

  // P0 存有滤波器抽头

  R0=[I0++] || R1=[I1++]; // 设置R0和R1的初始值

  A1=A0=0; // 将累加器置零

  LSETUP (loop1, loop1) LC0 = P0;//设置内部循环

  loop1: A1+=R0.L*R1.L, A0+=R0.H*R1.H||R0=[I0++]||R1=[I1++]; //计算

  除了具有所描述的用于内积的特性外,上面所示的FIR算法也可使用循环缓冲。


  循环缓冲器不需要直接取余运算。在C代码片段中,%(取余)运算符可提供一种用于循环缓冲的机理。正如汇编内核中所示,这些取余运算符不能被编 译为内循环中的其他指令。相反,数据地址发生器寄存器I0和I1可在外循环中配置,以便在循环到达系数缓冲器边界时能够自动返回起始处。

  FFT算法

  快速傅立叶变换(FFT)是许多信号处理算法不可缺少的一部分,其特点之一是输入向量按照连续时间顺序排列,但输出按比特翻转顺序排列。大多数传统的通用处理器要求程序员用单独的程序整理比特翻转输出。在DSP平台上,比特翻转可用于寻址引擎。

  比特翻转寻址在实现FFT时不需要单独的比特翻转程序,允许硬件自动将FFT算法的输出进行比特翻转,无须程序员编写额外的程序,从而改进了性能。

  除了上面所提到的指令外,有些处理器也包括额外一套专用指令以支持多种应用。提供这些指令的目的就是进一步提高对算法的处理能力,例如维特比算法、Huffman编码以及许多其他比特操作程序。

Blackfin汇编语言之程序流程控制


Blackfin常用指令均摘录自blackfin编程参考手册,以方便查阅。

Blackfin流程控制指令有:

1. jump
2. if CC jump
3. call
4. rts, rti, rtx, rtn, rte
5. lsetup, loop

分别简介之。

* jump

General Form
JUMP (destination_indirect)
JUMP (PC + offset)
JUMP offset
JUMP.S offset
JUMP.L offset

Syntax
JUMP ( Preg ) ;
/*indirect to an absolute (not PC-relative)address(a)*/
JUMP ( PC + Preg ) ; /* PC-relative, indexed (a)*/
JUMP pcrel25m2 ; /* PC-relative, immediate (a) or (b)*/
JUMP.S pcrel13m2 ; /*PC-relative, immediate, short (a)*/
JUMP.L pcrel25m2 ; /* PC-relative, immediate, long (b)*/
JUMP user_label ;
/* user-defined absolute address label,resolved by the
assembler/linker to the appropriate PC-relative
instruction (a) or (b) */

Syntax Terminology
Preg: P5–0, SP, FP
pcrelm2: undetermined 25-bit or smaller signed, even
relative offset, with a range of –16,777,216
through 16,777,214 bytes
(0xFF00 0000 to 0x00FF FFFE)
pcrel13m2: 13-bit signed, even relative offset, with a
range of –4096 through 4094 bytes (0xF000 to
0x0FFE)
pcrel25m2: 25-bit signed, even relative offset, with a
range of –16,777,216 through 16,777,214 bytes
(0xFF00 0000 to 0x00FF FFFE)
user_label: valid assembler address label, resolved by
the assembler/linker to a valid PC-relative offset

注:1(a)16bit指令长度,(b)32bit指令长度
(bp)Branch Prediction
2。跳转地址必须偶地址对齐(16bit-address)

* if cc jump

General Form
IF CC JUMP destination
IF !CC JUMP destination

Syntax
IF CC JUMP pcrel11m2 ;
/* branch if CC=1, branch predicted as not taken (a)*/
IF CC JUMP pcrel11m2 (bp) ;
/* branch if CC=1, branch predicted as taken (a) */
IF !CC JUMP pcrel11m2 ;
/* branch if CC=0, branch predicted as not taken (a)*/
IF !CC JUMP pcrel11m2 (bp) ;
/* branch if CC=0, branch predicted as taken (a) */
IF CC JUMP user_label ;
/*user-defined absolute address label, resolved by the
assembler/linker to the appropriate PC-relative
instruction (a) */
IF CC JUMP user_label (bp) ;
/* user-defined absolute address label, resolved by the
assembler/linker to the appropriate PC-relative
instruction (a) */
IF !CC JUMP user_label ;
/* user-defined absolute address label, resolved by the
assembler/linker to the appropriate PC-relative
instruction(a) */
IF !CC JUMP user_label (bp) ;
/* user-defined absolute address label, resolved by the
assembler/linker to the appropriate PC-relative
instruction (a) */

Syntax Terminology
pcrel11m2: 11-bit signed even relative offset, with a
range of –1024 through 1022 bytes (0xFC00 to 0x03FE)
this value can optionally be replaced with an
address label that is evaluated and replaced during
linking.
user_label: valid assembler address label, resolved by
the assembler/linker to a valid PC-relative offset

* call

General Form
CALL (destination_indirect)
CALL (PC + offset)
CALL offset

Syntax
CALL ( Preg ) ;
/*indirect to an absolute (not PC-relative) address (a)*/
CALL ( PC + Preg ) ; /* PC-relative, indexed (a) */
CALL pcrel25m2 ; /* PC-relative, immediate (b) */
CALL user_label ; /*user-defined absolute address label,
resolved by the assembler/linker to the appropriate
PC-relative instruction (a) or (b) */

Syntax Terminology
Preg: P5–0, SP, FP
pcrel25m2: 25-bit signed, even, PC-relative offset; can
be specified as a symbolic address label, with a
range of –16,777,216 through 16,777,214 (0xFF00 0000
to 0x00FF FFFE) bytes.
user_label: valid assembler address label, resolved by
the assembler/linker to a valid PC-relative offset

* RTS, RTI, RTX, RTN, RTE (Return)

General Form
RTS, RTI, RTX, RTN, RTE

Syntax
RTS ; // Return from Subroutine (a)
RTI ; // Return from Interrupt (a)
RTX ; // Return from Exception (a)
RTN ; // Return from NMI (a)
RTE ; // Return from Emulation (a)

Types of Return Instruction



* LSETUP, LOOP

General Form
There are two forms of this instruction. The first is:

LOOP loop_name loop_counter
LOOP_BEGIN loop_name
LOOP_END loop_name

The second form is:

LSETUP (Begin_Loop, End_Loop)Loop_Counter

Syntax
For Loop0

LOOP loop_name LC0 ; /* (b) */
LOOP loop_name LC0 = Preg ; /*autoinitialize LC0 (b)*/
LOOP loop_name LC0 = Preg >> 1 ; /* autoinit LC0(b) */
LOOP_BEGIN loop_name ;
/* define the 1st instruction of loop(b)*/
LOOP_END loop_name ;
/* define the last instruction of the loop (b) */
/* use any one of the LOOP syntax versions with a
LOOP_BEGIN and a LOOP_END instruction. The name of the
loop (“loop_name” in the syntax) relates the three
instructions together. */
LSETUP ( pcrel5m2 , lppcrel11m2 ) LC0 ; /* (b) */
LSETUP ( pcrel5m2 , lppcrel11m2 ) LC0 = Preg ;
/* autoinitialize LC0 (b) */
LSETUP ( pcrel5m2 , lppcrel11m2 ) LC0 = Preg >> 1 ;
/* autoinitialize LC0 (b) */

For Loop1

LOOP loop_name LC1 ; /* (b) */
LOOP loop_name LC1 = Preg ; /* autoinitialize LC1 (b)*/
LOOP loop_name LC1 = Preg >> 1;/*autoinitialize LC1 (b)*/
LOOP_BEGIN loop_name ;
/* define the first instruction of the loop (b) */
LOOP_END loop_name ;
/* define the last instruction of the loop (b) */
LSETUP ( pcrel5m2 , lppcrel11m2 ) LC1 ; /* (b) */
LSETUP ( pcrel5m2 , lppcrel11m2 ) LC1 = Preg ;
/* autoinitialize LC1 (b) */
LSETUP ( pcrel5m2 , lppcrel11m2 ) LC1 = Preg >> 1 ;
/* autoinitialize LC1 (b) */

Syntax Terminology
Preg: P5?b>C0 (SP and FP are not allowed as the source
register for this instruction.)
pcrel5m2: 5-bit unsigned, even, PC-relative offset; can
be replaced by a symbolic label. The range is 4 to 30.
lppcrel11m2: 11-bit unsigned, even, PC-relative offset
for a loop; can be replaced by a symbolic label. The
range is 4 to 2046 (0x0004 to 0x07FE).
loop_name: a symbolic identifier

Blackfin包含两组寄存器用于硬件循环:
Loop_Top (LTx): LT0,LT1
Loop_Bottom (LBx): LB0,LB1
Loop_Count (LCx): LC0,LC1

2008年11月22日

Blackfin 处理器硬件设计注意事项

Blackfin 处理器硬件设计注意事项

概述:
为采用blackfin处理器设计产品的工程师避免犯一般错误。除了这个文档
之外,设计者应当读相关的规格书,硬件参考手册,以及所用处理器的堪误
表(可以从ADI网站中下载到)。

NMI极性:
所使用的处理器的双极性非屏蔽中断引脚。个别处理器(如ADSP-BF531/
BF532/BF533/BF535和BF561),NMI引脚激活为高。而其他处理器,NMI
引脚激活为低以便于同标准的外围设计连接。同样的,注意NMI引脚是否可
用以它的非激活状态。
注:不要让NMI悬空。

5V电压容许
直接将5V电压连接到引脚有可能使其损坏、产生故障。Blackfin处理器输
出连接到5V设备输入引脚可能左漂浮或可能被上拉到5V。大多数处理器引脚
不能容忍5V电压。除了两线接口(TWI)引脚。其他所有引脚电压变化应当
保证在规格书中规定的电压值或小于其许可范围的最大值,高电压中采用限
流电阻不能起到完全的保护作用。

不使用引脚处理:
看数据手册中的引脚描述列表。

信号完整性:
快速的信号上升时间和下降时间是引起信号完整性的主要问题。处理器的
每个引脚上升/下降斜率不一样。同样的,一些引脚对噪音和其他引脚的信
号反射具有更大的敏感性。采用简单的信号完整性处理方法防止线上传播反
射信号干扰时钟和同步信号,短的走线和连续终止对以下的信号很重要:
CLINK引脚应当有相应的驱动阻抗匹配。
SPORT口信号(TCLK,RCLK,RFS,TFS)应当采用终结。
PPI引脚,如PPI——CLK和同步信号也同样受益于标准的信号完整性技术。
SDRAM时钟,控制,地址和数据对连续的终于有益并减少不必要的EMI。
假如有多个信号源的信号,要保证走线短是很困难的,ADI网站上提供的
IBIS模块有助于对这些信号的处理。

测试点和信号提取:
对CLKOUT,SCLK,BANK选择,PPICLK和RESET信号设置测试点可以方便调
试。如果选择的如引导模式(BMODE)引脚直接连到电源或地,对于BGA封装
的处理器将没法做到。对于调试,使用上拉或下拉电阻比直接接电源或地更
好。

旁路电容:
对于更高速度的电路对内部供电端加上适当的旁路电容。电路中的有害感
应电容对高频电路具有很大的影响。有两件事需要考虑:当处理器运行速度
高于100MHz时,首先电容应当少,走线应当短以减小感应系数。0402的表贴
电容比更大尺寸的电容效果要明显。第二,小电容值将更容易引起LC电路的
自激。低于50MHZ的采用几个0.1uF的电容。高于500MHz的采用VDD——INT旁
0.1,0.01,0.001和100pF的组合电容。

复位:
Blackfin处理器的引脚没有滞后作用,因此,要求一个单调和上升或下降。
所以复位引脚不能直接连到R/C延时电路上,Blackfin处理器对这种电路噪
音比较敏感。所以复位引脚应当有一个复位芯片生产一个复位信号供给。

JTAG:
JTAG接口的完整应用,参考Analog Devices JTAG Emulation Technical
Reference (EE-68)[1]

PF引脚作为输出使用:
PF引脚作为输出应当接上拉或下拉以确定复位时的状态。

使用EZ-KIT Lite原理图
EZ-KIT Lite评估系统的原理图是一个很好的设计参考。因为EZ-KIT Lite
是一个评估和开发板,还提供一些例子

总线请求:
总线请求引脚(/BR)要求在所有的设计中加上拉电阻。如果不加上拉电阻
在没有任何外设驱动的情况下可能产生错误的总线请求。