FPGA 总结
系统架构确定,下一步就是FPGA与各组成器件之间互联的问题了。通常来说,CPU和FPGA的互联接口,主要取决两个要素:
灵活性的陷阱
如果说用一个词来描述FPGA的特性,灵活性肯定名列前茅。
从零开始调试FPGA
“合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。” 老子《道德经》
对于新手来说,如何上手调试FPGA是关键的一步。
对于每一个新设计的FPGA板卡,也需要从零开始调试。
那么如何开始调试/p>
下面介绍一种简易的调试方法。
(1) 至少设定一个输入时钟 input sys_clk;
(2) 设定输出 output [N-1:0] led;
(3)设定32位计数器 reg [31:0] led_cnt;
(4) 时钟驱动计数器开始工作
always@(posedge sys_clk)
led_cnt
(5)输出led信 。
assign led = led_cnt[M:N];
程序完成。
(6)设定管教约束
如果为XILINX FPGA ,在UCF文件中 NET “sys_clk” LOC = 管脚名称
如果为ALTERA FPGA ,在QSF文件中,添加 set_location_assignment 管脚名称 -to sys_clk
其他管脚,可依次类推。
(7)编译,布局、布线,生成配置文件。
XILINX 生成BIT文件。
ALTERA 生成SOF文件
(8)连接JTAG,下载相应的配置文件。
(9)观察是否闪灯(肉眼可见)。
关于闪灯的解释如下:
assign led = led_cnt[M:N]; led_cnt 为32bit的信 ,需要几个闪灯,则根据输入时钟的频率和肉眼能够分辨的时间(100ms)。如输出时钟为25Mhz。则闪灯看见的位置能够分批到10hz。需分频2.5M= 32‘h2625A0,因此,则需要输出至少为led_cnt[21]位,才能看到闪灯。
虽然程序简单,但是,通过调试可以确认:
(1)首先可确定JTAG下载器的正确连接,能够正常下载下载文件。如不能,常见问题包括
(一)检查是否安装驱动。
(二)下载器是否由红灯变成黄灯/绿灯。如红灯亮一般情况下,JTAG的与电路板VCC没有供电。
(三)检查JTAG连接的线序。
(四)检查JTAG电路,检查原理图上TMS,TDI,TDO的上拉和下拉电阻是否与datasheet中一致。
通过以上四种方式,可排除绝大部分JTAG下载的错误。
(2)可以判断晶振是否起振,下载后无灯闪。
(一)首先,示波器查看晶振频率,观察晶振的输出,如无输出,查看晶振的电源和地信 ,如电源正常,而晶振无反应,则更换晶振。
(二)如无示波器,也有替代的方法,通过嵌入式逻辑分析仪抓信 (任意信 )。如逻辑分析仪点击采样后无反应,则无时钟输入。
这是因为逻辑分析仪也需要时钟进行逻辑值的存储。
(3)如正常下载后闪灯,证明该FPGA板卡硬件设计上能够达到最低限度的FPGA调试状态。
最后,说明一下,为什么是闪灯而不是亮灯的程序,这是因为,首先闪灯可以判断外部晶振工作正常,并且由于LED等通常为上拉,也就是说逻辑值0表示灯亮,而也不排除某硬件工程师非要下拉。逻辑1表示亮。因此采用闪灯更加方便。
问题:为什么LED灯值为什么要上拉/p>
这是因为:LED上拉后,需要灯亮时电流由外部电源提供,而下拉,灯亮时电流由芯片的CMOS电路驱动。这种在设计中应避免。
架构设计漫谈(一)流驱动和调用式
勿用讳言,现在国内FPGA开发还处于小作坊的开发阶段,一般都是三、四个人,七八台机器.小作坊如何也能做出大成果。这是每个FPGA工程师都要面临的问题。架构设计是面临的第一关。经常有这样的项目,需求分析,架构设计匆匆忙忙, 称一两个月开发完毕,实际上维护项目就花了一年半时间。主要包括几个问题,一,性能不满足需求。二,设计频繁变更。三,系统不稳定,调试问题不收敛。
架构设计漫谈(二)稳定压倒一切
敏捷开发宣言中,有一条定律是“可以工作的软件胜过面面俱到的文档”。如何定义可可以工作的,这就是需求确定后架构设计的首要问题。而大部分看这句话的同志更喜欢后半句,用于作为不写文档的借口。
FPGA的架构设计最首先可以确定就是外接接口,就像以前说的,稳定可靠的接口是成功的一半。接口的选择需要考虑几个问题。
1, 有无外部成熟IP。一般来说,ALTERA和XILINX都提供大量的接口IP,采用这些IP能够提升研发进度,但不同IP在不同FPGA上需要不同license,这个需要通过代理商来获得(中国国情,软件是不卖钱的)。
2, 自研接口IP,能否满足时间、进度、稳定性、及兼容性的要求。
案例1设计一个 络接口在逻辑设计上相对简单,比如MII接口等同于4bit数据线的25MHZ样,而RGMII可以使用双沿125Mhz的采样专用的双沿采样寄存器完成(使用寄存器原语)。但是如何支持与不同PHY连接一个兼容性问题(所谓设计挑PHY的问题,这个问题后面详述)。
不能只是考虑编写verilog代码仿真能对就行,接口设计应该站在系统的角度来看问题,问题不是孤立的,还是互相联系。
设计中,如果需要存储大量数据,就需要在外部设计外部存储器,这是因为FPGA内部RAM的数量是有限的。是采用SRAM、DDR2、DDR3。这就需要综合考虑存储数据大大小,因为SRAM的容量也有限,但是其接口简单,实现简单方便,且读取延时较小。DDR2、DDR3的容量较大,接口复杂,但FPGA内部有成熟IP可用,但是读取的延时较大,从发起读信 到读回数据一般在十几个时钟周期以上。如果对数据时延有要求,需要上一次存储数据作为下一次使用,且数据量不太大(几百K到几兆),则SRAM是较好的选择。而其他方面DDR2/DDR3是较好的选择。为什么不用SDRAM或者DDR。这是因为设计完毕,采购会告诉你,市场上这样老的芯片基本都停产了。
FPGA接口在设计选择的原则就是:能力够用,简单易用。特别值得一提的是高速SERDES接口,最好使用厂商给的参考设计,有硬核则不选择软核,测试稳定后,一定要专门的位置约束,避免后面添加的逻辑拥挤后影响到接口时序,也可避免接口设计人员与最终的逻辑设计人员扯皮(不添加过多逻辑,接口是好用的)。一个分析高速SERDES的示波器,采样频率至少20G甚至更高以上,动辄上百万,出现问题,不一定有硬件条件可调试。
回到开头,如何定义“可用的”设计,稳定我想是前提,而接口的稳定性更是前提的前提。这里稳定包括,满负荷边界测试,量产、环境试验等一系列稳定可靠。而在架构设计中,就选择成熟的接口,能有效的避免后续流程中的问题,从源头保证产品的质量。
架构设计漫谈(三)时钟和复位
接口确定以后,FPGA内部如何规划先需要考虑就是时钟和复位。
时钟:根据时钟的分类,可以分为逻辑时钟,接口时钟,存储器时钟等;
接口名称
IP输入时钟
备注
MII
25Mhz
RGMII/GMII
125Mhz
XAUI
156.25Mhz
差分
IP内部倍频使用
PCI
33Mhz
PCI-e
100Mz
差分输入
IP内部倍频使用
因为有了DCM/PLL这些专用产生时钟的器件,似乎产生任意时钟输出都是可能是,但实际例化的结果,时钟的输出只能选取某些范围和某些频率,取决于输入时钟和分频系数,CLK_OUT = CLK_IN *(M/N) 。这些分频系数基本取整数,其产生的频率也是有限的值。
复位:根据复位的分类,FPGA内部复位可以分为硬复位,逻辑复位、软复位等;
硬复位:故名思议,即外部引脚引入的复位,可以在上电时给入,使整个FPGA逻辑配置完成后,能够达到稳定的状态,这种复位重要性在于复杂单板上除了FPGA外,可能还有多个器件(CPU、DSP),其上电顺序不同,在未完成全部上电之前,其工作状态为不稳定状态。这种复位引脚可以通过专用时钟管脚引入,也可通过普通I/O引入,一般由单板MCU或者CPLD给出。
逻辑复位:则是由FPGA内部逻辑产生,例如可以通过计数产生,等待一段时间开始工作,一般等待外部某些信 准备好,另一种FPGA内部逻辑准备好的状态信 ,常见的有DCM/PLL的LOCK信 ;只有内部各逻辑准备好后,FPGA才能正常工作。另外FPGA内部如设计逻辑的看门狗的话,其产生的复位属于这个层次。
软复位:严格的说,应属于调试接口,指FPGA接收外部指令产生的复位信 ,用于复位某些模块,用于定位和排除问题,也属于可测性设计的一部分。例如FPGA通过EMIF接口与CPU连接,内部设定软复位寄存器,CPU通过写此寄存器可以复位FPGA内部单元逻辑,通过写内部寄存器进行软复位,是复杂IP常用的功能接口。调试时,FPGA返回错误或无返回,通过软复位能否恢复,可以迅速定位分割问题,加快调试速度。
复位一般通过与或者或的方式(高电平或、低电平与),产生统一的复位给各模块使用。模块软复位信 ,只在本模块内部使用。
问题:同步复位好、还是异步复位好XILINX虽然推荐同步复位,但也不一概而论,复位的目的是使整个系统处于初始状态,这根据个人写代码经验,这些操作都可以,前提是整个设计为同步设计,时钟域之间相互隔开,复位信 足够长,而不是毛刺。下面推荐一种异步复位的同步化方式,其电路图如下:
时钟和复位基本上每个模块的基本输入,也是FPGA架构上首先要规划的部分,而不要用到才考虑,搞的整个设计到处例化DCM或者输出LOCK进行复位,这些对于工程的可维护性和问题定位都没有益处。《治家格言》说:“宜未雨而绸缪,毋临渴而掘井。这与FPGA时钟和复位的规划是同一个意思。
架构设计漫谈(四)并行与复用
FPGA其在众多器件中能够被工程师青睐的一个很重要的原因就是其强悍的处理能力。那如何能够做到高速的数据处理,数据的并行处理则是其中一个很重要的方式。
数据的并行处理,从结构上非常简单,但是设计上却是相当复杂,对于现有的FPGA来说,虽然各种FPGA的容量都在增加,但是在有限的逻辑中达到更高的处理能力则是FPGA工程师面临的挑战。常用并行计算结构如下图所示:
上图中:前端处理单元负责将进入数据信息,分配到多个计算单元中,图中为3个计算单元(几个根据所需的性能计算得出)。然后计算单元计算完毕后,交付后端处理单元整合为统一数据流传入下一级。如果单个计算单元的处理能力为N ,则通过并行的方式,根据并行度M,其计算能力为N*M;在此结构中,涉及到几个问题:
一, 前端处理单元如何将数据分配到多个计算单元,其中一种算法为round-robin,轮流写入下一级计算单元,这种方式一般使用用计算单元计算数据块的时间等同。更常用的一种方式,可以根据计算单元的标示,即忙闲状态,如果哪个计算单元标示为闲状态,则分配其数据块。
二, 计算单元和前后端处理之间如何进行数据交互。一般来说,计算单元处理频率较低,为关键路径所在。前后端处理流量较大,时钟频率较高,因此通过异步FIFO连接,或者双端口RAM都是合适的方式。如果数据可分块计算,且块的大小不定,建议使用FIFO作为隔离手段,同时使用可编程满信 ,作为前端处理识别计算模块的忙闲标示。
三, 如果数据有先后的标示,即先计算的数据需要先被送出,则后端处理模块需要额外的信 ,确定读取各个计算模块的顺序。这是因为:如果数据等长,则计算时间等长,则先计算的数据会先被送出。但是如果数据块不等长,后送入的小的数据块肯能先被计算完毕,后端处理单元如果不识别先后计算的数据块,就会造成数据的乱序。这可以通过前端计算单元通过小的FIFO通知后端计算单元获知首先读取那个计算单元输出的数据,即使其他计算单元输出已准备好,也要等待按照顺序来读取。
数据的并行处理是FPGA常用的提升处理性能的方法,其优点是结构简单,通过计算单元模块的复用达到高性能的处理。缺点,显而易见就是达到M倍的性能就要要耗费M倍逻辑。
与之相反减少逻辑的另一种方式,则是复用,即一个处理能力较强的模块,可以被N的单元复用,通过复用,而不用每个单元例化模块,可以达到减少逻辑的效果,但控制复杂度就会上升。其结构图如下所示:
上图复用的结构图中,分别介绍了流过模式复用和调用模式复用。流过模式下,计算单元处理多路数据块,然后将数据块分配到多路上,这种情况下,通过round-robin可以保证各个通路公平机会获得计算单元。其处理思路与上图描述并行处理类似。
调用模式下,计算单元被多个主设备复用,这种架构可以通过总线及仲裁的方式来使各个主设备能够获取计算单元的处理(有很多成熟的例子可供使用,如AHB等)。如果多个主设备和多个计算单元的情况,则可以不通过总线而通过交换矩阵,来减少总线处理带来的总线瓶颈。
实际应用场合,设计的架构都应简单实用为好,交互矩阵虽然实用灵活,但其逻辑量,边界测试验证的难度都较大,在需要灵活支持多端口互联互通的情况下使用,可谓物尽其用。但如果仅仅用于一般计算单元能力复用的场景,就属于过度设计,其可以通过化简成上述两种简单模式,达到高速的数据处理的效果。
并行和复用,虽然是看其来属性相反的操作,但其本质上就是通过处理能力和逻辑数量的平衡,从而以最优的策略满足项目的需要。设计如此,人生亦然。
架构设计漫谈(五)数字电路的灵魂-流水线
流水线,最早为人熟知,起源于十九世纪初的福特汽车工厂,富有远见的福特,改变了那种人围着汽车转、负责各个环节的生产模式,转变成了流动的汽车组装线和固定操作的人员。于是,工厂的一头是不断输入的橡胶和钢铁,工厂的另一头则是一辆辆正在下线的汽车。这种改变,不但提升了效率,更是拉开了工业时代大生产的序幕。
架构流水的好处一目了然,但另一个问题,对于某些设计就需要谨慎处理,那就是时延。对于进入流水线的信息A,如果接入的流水处理的模块越多,其输出时的时延也越高,因此如对处理时延要要求的设计就需要在架构设计时,谨慎对待添加流水线。架构设计时,可以通过处理各个单元之间的延时估计,从而评估系统的时延,避免最终不能满足时延短的需求,返回来修改架构。
流水架构在另种设计中则无能为力,那就是带反馈的设计,如下图所示:
图中,需要处理模块的输入,需要上一次计算后的结果的值,也就是输出要反馈回设计的输入。例如某帧图像的解压需要解压所后的上一帧的值,才能计算得出。此时,流水的处理就不能使用,若强行添加流水,则输入需等待。
流水应用在调用式的设计中,可以通过接口与处理流水并行达到。即写入、处理、读出等操作可以做到流水式架构,从而增加处理的能力。
流水是FPGA架构设计中一种常用的手段,通过合理划分流水层次,简化设计,优化时序。同时流水在模块设计中也是一种常用的手段和技巧。这将在后续重陆续介绍。,流水本身简单易懂,而真正能在设计中活用,就需要对FPGA所处理的业务有着深刻的理解。正如那就话,知晓容易,践行不易,且行且珍惜。
设计不是凑波形(一)FIFO(上)
FIFO是FPGA内部一种常用的资源,可以通过FPGA厂家的的IP生成工具生成相应的FIFO。FIFO可分为同步FIFO和异步FIFO,其区别主要是,读写的时钟是否为同一时钟,如使用一个时钟则为同步FIFO,读写时钟分开则为异步FIFO。一般来说,较大的FIFO可以选择使用内部BLOCK RAM资源,而小的FIFO可以使用寄存器资源例化使用。
信
数据信
读信
rd_en
读数据
dout
读空信
empty
写信
wr_en
写数据
din
写满信
full
(1) 数据的缓冲,如模型图所示,如果数据的写入速率高,但间隔大,且会有突发;读出速率小,但相对均匀。则通过设置相应深度的FIFO,可以起到数据暂存的功能,且能够使后续处理流程平滑,避免前级突发时,后级来不及处理而丢弃数据。
(2) 时钟域的隔离。对于不同时钟域的数据传递,则数据可以通过FIFO进行隔离,避免跨时钟域的数据传输带来的设计与约束上的复杂度。
其次,另一更容易出错的问题,就是空信 。对于FIFO来说,在读过程中出现空信 ,则其没有代表该值没有被读出,对于读信 来说,如设定读出一定长度的值,只在一开始检测非空,如状态机的触发信 ,容易出现过程中间也为空的信 ,会导致某些数据未读出,特别是写速满而读速快的场景下。 因此rden与!empty信 要一起有效才算将数据读出。
空信 处理相对容易出错,懒人自有笨方法,下面介绍一种应用于数据帧处理的FIFO使用方式,只需在读开始检测空信 即可,可以简化其处理读数据的流程:
-设计不是凑波形(二)FIFO(下)
FIFO在FPGA设计中除了上篇所介绍的功能之外, 还有以下作为以下功能使用:
(1) 内存申请
在软件设计中,使用malloc()和free()等函数可以用于内存的申请和释放。特别是在有操作系统的环境下,可以保证系统的内存空间被动态的分配和使用,非常的方便。如果在FPGA内部实现此动态的内存分配和申请,相对来说较为复杂,例如某些需要外部数据存储且需动态改变的应用需求下,需要对FPGA外部DDR(或SRAM等)的存储空间,进行动态的分配和释放。通过使用FIFO作为内存分配器,虽然比不上软件的灵活和方便,但是使用也较为简便。
举例说明假设外部存储空间为8Mbyte,可将其划分为8192个1Kbyte空间。并将数值0-8191存储FIFO中,FIFO内部存储所标示可用的内存空间。如下图所示。
首先,进行内存的初始化,即将0-8191写入FIFO中。
如需申请内存后,从FIFO中读取值A,然后根据A的标示,写入A所指示的外部存储区(DDR)中相应的位置,即申请{A,10’h0_00} ->{A,10’h3_FF}的空间区域。
如释放内存后,即可向FIFO中写入相应的值。即可保证下次该空间能够被设计使用。
在此种设计中,FIFO承担了内存分配和释放器的角色。此时只能申请或释放最小单元倍数的内存空间,如本例所示:为1Kbit。如FIFO读空,则代表申请内存失败,需要等待其他块内存释放后再写入FIFO中,才能再次申请。
(2) 串并转换
对于串并转换,可能对于FPGA工程师来说,非常常见,但是如果有专门的IP实现此功能,可简化设计,减少出错及验证的工作量。例如:对于外部输入的需要进行串并转换的信 ,并进行存储的信 ,如设计进行串并转换在存储等操作,设计,可以直接通过例化读写位宽不一致的FIFO,例如1入8出的FIFO,可直接将外部输入信 直接转换成8BIT信 并进行存储后,供后续处理使用(其他的)。
(3) 业务优先级划分
通过FIFO设置不同水位线,可以划分不同的业务优先级,保证高业务优先级数据流在带宽受限时,优先通过,而低业务优先级只能在满足高优先级需求后有多余的带宽时才能通过。并且可以划分多个优先级,满足多种业务的需求。设计将在以后篇幅中详述。
(4)固定带宽设定
通过对FIFO接口的读出使能,能够保证实现固定带宽的输出,例如FIFO读接口为32bit,而读时钟为50Mhz,则输出为1.6Gbit/S。如实现固定带宽的输出(如1Gbit/S),有两种方式,一种可以通过降低时钟频率到31.25Mhz。另一种方式,可通过读信 中间插入等待周期,如果读出长度为N的数据所需时钟周期为M,则需等待(3M/5)的周期,从而降低至1Gbit/S的处理能力,这在某些需要进行流量限制的业务方式中使用。
对于FIFO来说,作为FPGA内部资源的一个常用器件,最常见应用于异步时钟域划分和缓冲数据,但不仅限于此,简化设计、减少耦合、输入输出接口固定,便于仿真和验证,都是使用FIFO带来的设计上的益处。
设计不是凑波形(三)RAM
在FPGA内部资源中,RAM是较为常用的一种资源。
通过查看datasheet的中RAM能够配置的方式,从而能够正确的使用RAM资源,从而达到高的利用效率。可以看出,RAM9K其应用方式受限,主要是因为RAM的端口的连接信 受限,例如:该RAM9K的读端口最大支持36根信 线,因此对于单端口其支持的宽度为36,双端口为18(两个端口,总共36根数据线),作为FPGA来说,其布线资源是有限的,不可能无限制的增加其端口数。
RAM例化时,有时需要初始化RAM,ALTERA和XLINX的初始化方法如下所示:
(1)ALTERA RAM中,例化时为MIF文件,其格式为:
DEPTH = 32; – The size of memory in words
WIDTH = 8; – The size of data in bits
ADDRESS_RADIX = HEX; – The radix for address values
DATA_RADIX = HEX; – The radix for data values
CONTENT – start of (address : data pairs)
BEGIN
00 : 0; – memory address : data
01 : 1;
END;
(2)在XILINX的RAM中,RAM出示化文件为COE文件,其格式为:
MEMORY_INITIALIZATION_VECTOR= 初始化向量
值得注意的是:XILINX的RAM初始化后会自动生成MIF文件,而此mif文件与ALTERA mif文件格式不同。不能用于初始化ALTERA的 RAM。
module ram(
clk, wr,addr,din,dout
);
input clk;
input [7:0] addr;
input wr;
input [31:0] din;
output [31:0] dout;
reg [31:0] mem [0:255];
reg [31:0] dout;
always@(posedge clk)
if(wr)
mem[addr]
always @(posedge clk)
dout = mem[addr] ;
endmodule
上述描述可以被描述成RAM,自动产生RAM.其例化的 告为:
=========================================================================
=========================================================================
Performing bidirectional port resolution…
Synthesizing Unit .
Unit synthesized.
=========================================================================
HDL Synthesis Report
Macro Statistics
RAMs : 1
256×32-bit single-port RAM : 1
Registers : 1
32-bit register : 1
=========================================================================
写在coding之前的铁律
写在coding之前的那些铁律
(1)注释: 好的代码首先必须要有注释,注释至少包括文件注释,端口注释,功能语句注释。
(2)语句:
开始写代码是,在FPGA设计中,特别是在可综合的模块实现中,verilog的语句是很固定的。在FPGA的设计中,不外乎时序逻辑和组合逻辑,除此之外,别无他法。对于开始功能编码来说,只需知道组合逻辑信 即可生效,时序逻辑在时钟的下一拍起效就够了。
下面是编码的实例。
组合逻辑:两种组合逻辑的描述,其功能是一致的。
assign A = B 1 : D 2 :3;
always@(*)
组合逻辑 如果是异步复位的话,描述如下
alw
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!