① 如何用fpga实现算法的硬件加速
首先,利用传统的软件技巧来优化算法,然后将其转向定制指令以加速算法。我们将讨论不同实现方法的性能比较和折衷。
CRC算法可用来校验数据在传输过程中是否被破坏。这些算法很流行,因为它们具有很高的检错率,而且不会对数据吞吐量造成太大影响,因为CRC校验位被添加进数据信息中。但是,CRC算法比一些简单的校验和算法有更大的计算量要求。尽管如此,检错率的提高使得这种算法值得去实施。
一般说来,发送端对要被发送的消息执行CRC算法,并将CRC结果添加进该消息中。消息的接收端对包括CRC结果在内的消息执行同样的CRC操作。如果接收端的结果与发送端的不同,这说明数据被破坏了。
CRC算法是一种密集的数学运算,涉及到二元模数除法(molo-2 division),即数据消息被16或32位多项式(取决于所用CRC标准)除所得的余数。这种操作一般通过异或和移位的迭代过程来实现,当采用16位多项式时,这相当于每数据字节要执行数百条指令。如果发送数百个字节,计算量就会高达数万条指令。因此,任何优化都会大幅提高吞吐量。
代码列表1中的CRC函数有两个自变量(消息指针和消息中的字节数),它可返回所计算的CRC值(余数)。尽管该函数的自变量是一些字节,但计算要逐位来执行。该算法并不高效,因为所有操作(与、移位、异或和循环控制)都必须逐位地执行。
列表1:逐位执行的CRC算法C代码。
/*
* The width of the CRC calculation and result.
* Modify the typedef for a 16 or 32-bit CRC standard.
*/
typedef unsigned char crc;
#define WIDTH (8 * sizeof(crc))
#define TOPBIT (1 << (WIDTH - 1))
crc crcSlow(unsigned char const message[], int nBytes)
{
crc remainder = 0;
/*
* Perform molo-2 division, a byte at a time.
*/
for (int byte = 0; byte < nBytes; ++byte)
{
/*
* Bring the next byte into the remainder.
*/
remainder ^= (message[byte] << (WIDTH - 8));
/*
* Perform molo-2 division, a bit at a time.
*/
for (unsigned char bit = 8; bit > 0; "bit)
{
/*
* Try to divide the current data bit.
*/
if (remainder & TOPBIT)
{
remainder = (remainder << 1) ^ POLYNOMIAL;
}
else
{
remainder = (remainder << 1);
}
}
}
/*
* The final remainder is the CRC result.
*/
return (remainder);
}
1.传统的软件优化
图3:带CRC外围电路和DMA的系统模块示意图。
让我们看一下如何利用传统的软件技巧来优化CRC算法。因为CRC操作中的一个操作数,即多项式(除数)是常数,字节宽CRC操作的所有可能结果都可以预先计算并存储在一个查找表中。这样,通过一个读查找表动作就可让操作按逐个字节执行下去。
采用这一算法时,需要将这些预先计算好的值存储在存储器中。选择ROM或RAM都可以,只要在启动CRC计算之前将存储器初始化就行。查找表有256个字节,表中每个字节位置包含一个CRC结果,共有256种可能的8位消息(与多项式大小无关)。
列表2示出了采用查找表方法的C代码,包括生成查找表crcInit()中数值的代码。
列表2:采用查找表方法的CRC算法C代码。
crc crcTable[256];
void crcInit(void)
{
crc remainder;
/*
* Compute the remainder of each possible dividend.
*/
for (int dividend = 0; dividend < 256; ++dividend)
{
/*
* Start with the dividend followed by zeros.
*/
remainder = dividend << (WIDTH - 8);
/*
* Perform molo-2 division, a bit at a time.
*/
for (unsigned char bit = 8; bit > 0; "bit)
{
/*
* Try to divide the current data bit.
*/
if (remainder & TOPBIT)
{
remainder = (remainder << 1) ^ POLYNOMIAL;
}
else
{
remainder = (remainder << 1);
}
}
/*
* Store the result into the table.
*/
crcTable[dividend] = remainder;
}
} /* crcInit() */
crc crcFast(unsigned char const message[], int nBytes)
{
unsigned char data;
crc remainder = 0;
/*
* Divide the message by the polynomial, a byte at a time.
*/
for (int byte = 0; byte < nBytes; ++byte)
{
data = message[byte] ^ (remainder >> (WIDTH - 8));
remainder = crcTable[data] ^ (remainder << 8);
}
/*
* The final remainder is the CRC.
*/
return (remainder);
} /* crcFast() */
整个计算减少为一个循环,每字节(不是每位)有两个异或、两个移位操作和两个装载指令。基本上,这里是用查找表的存储空间来换取速度。该方法比逐位计算的方法要快9.9倍,这一提高对某些应用已经足够。如果需要更高的性能,可以尝试编写汇编代码或增加查找表容量以挤出更多性能来。但是,如果需要20、50甚至500倍的性能提高,就要考虑采用硬件加速来实现该算法了。
表1:各种规模的数据模块下CRC算法测试比较结果。
2.采用定制指令方法
CRC算法由连续的异或和移位操作构成,用很少的逻辑即可在硬件中简单实现。由于这一硬件模块仅需几个周期来计算CRC,采用定制指令来实现CRC计算要比采用外围电路更好。此外,无须涉及系统中任何其它外围电路或存储器。仅需要一个微处理器来支持定制指令即可,一般是指可配置微处理器。
当在硬件中实现时,算法应该每次执行16或32位计算,这取决于所采用的CRC标准。如果采用CRC-CCITT标准(16位多项式),最好每次执行16位计算。如果使用8位微处理器,效率可能不太高,因为装载操作数值及返回CRC值需要额外的周期。图2示出了用硬件实现16位CRC算法的内核。
信号msg(15..0)每次被移入异或/移位硬件一位。列表3示出了在64KB数据模块上计算CRC的一些C代码例子。该实例是针对Nios嵌入式处理器。
列表3:采用定制指令的CRC计算C代码。
unsigned short crcCompute(unsigned short *data_block, unsigned int nWords)
{
unsigned short* pointer;
unsigned short word;
/*
* initialize crc reg to 0xFFFF
*/
word = nm_crc (0xFFFF, 1); /* nm_crc() is the CRC custom instruction */
/*
* calculate CRC on block of data
* nm_crc() is the CRC custom instruction
*
*/
for (pointer = data_block; pointer < (data_block + nWords); pointer ++)
word = nm_crc(*pointer, 0) return (word);
}
int main(void)
{
#define data_block_begin (na_onchip_memory)
#define data_block_end (na_onchip_memory + 0xffff)
unsigned short crc_result;
unsigned int data_block_length = (unsigned short *)data_block_end - (unsigned short
*)data_block_begin + 1;
crc_result = crcCompute((unsigned short *)data_block_begin, data_block_length);
}
采用定制指令时,用于计算CRC值的代码是一个函数调用,或宏。当针对Nios处理器实现定制指令时,系统构建工具会生成一个宏。在本例中为nm_crc(),可用它来调用定制指令。
在启动CRC计算之前,定制指令内的CRC寄存器需要先初始化。装载初始值是CRC标准的一部分,而且每种CRC标准都不一样。接着,循环将为数据模块中的每16位数据调用一次CRC定制指令。这种定制指令实现方式要比逐位实现的方法快27倍。
3.CRC外围电路方法
如果将CRC算法作为硬件外围电路来实现,并利用DMA将数据从存储器转移到外围电路,这样还可以进一步提高速度。这种方法将省去处理器为每次计算而装载数据所需要的额外周期。DMA可在此外围电路完成前一次CRC计算的时钟周期内提供新的数据。图3示出了利用DMA、CRC外围电路来实现加速的系统模块示意图。
在64KB数据模块上,利用带DMA的定制外围电路可获得比逐位计算的纯软件算法快500倍的性能。要知道,随着数据模块规模的增加,使用DMA所获得的性能也随之提高。这是因为设置DMA仅需很少的开销,设置之后DMA运行得特别快,因为每个周期它都可以传递数据。因此,若只有少数字节的数据,用DMA并不划算。
这里所讨论的所有采用CRC-CCITT标准(16位多项式)的算法都是在Altera Stratix FPGA的Nios处理器上实现的。表1示出了各种数据长度的测试比较结果,以及大致的硬件使用情况(FPGA中的存储器或逻辑单元)。
可以看出,算法所用的硬件越多,算法速度越快。这是用硬件资源来换取速度。
② 在FPGA上快速实现MD5算法的新方法论文
在FPGA上快速实现MD5算法的新方法论文
摘 要 文章介绍了一种在FPGA上快速实现MD5算法的新方法,给出了优化设计的原理、实现的具体方法及其重要模块的设计实现方案。
关键词 MD5;FPGA;Verilog语言;集成电路;关键路径
1 引言
随着电子商务和网络通信的发展,网络信息安全的重要性越来越显着,信息加密、数字签名、数据的完整性认证、身份验证等成为信息安全领域的重要内容。MD5算法本身是为数字签名应用而设计的,随后也应用在信息验证技术当中。作为应用最广泛的安全散列算法,MD5算法的高效实现就成为研究的需要,MD5算法本身可以采用软件实现,但其性能受到处理器件性能的制约不能满足网络通信带宽日益增长的要求,因而通过硬件实现高速MD5 运算就成为需要。
2 MD5算法介绍
MD5 算法可以对任何长度不超过 264二进制位的消息产生128 位的单向散列消息摘要输出, RFC1321 标准中的MD5 算法主要步骤如下:
在一些初始化处理后,MD5以512位分组来处理输入文本,每一分组又划分为16个32位子分组。算法的输出由四个32位分组组成,将它们级联形成一个128位散列值。
(1)附加填充比特:填充消息使其长度恰好为一个比512位的倍数仅小64位的数。即对报文进行填充使报文的长度(比特数)与448模512同余。填充方法是附一个1在消息后面接所要求的多个比特0。
(2)附加长度值:在其后附上64位的消息长度(填充前)。如果消息长度大于 264,仅使用该长度的低64比特。这样,该域包含的长度值为初始长度模264 的值。
这两步的作用是使消息长度恰好是512位的整数倍(算法的其余部分要求如此),同时确保不同的消息在填充后不相同。
(3)初始化寄存器:四个32位初始化变量为:
它们也被称为链接变量(chaining variable)
(4)进行算法的主循环:这一步是算法的核心,它是一个包含四个大循环的64步函数,四个大循环结构相同,但每次使用的逻辑函数不同,每一个大循环由对512比特的16步操作组成,即每16步为一轮大循环。
每次操作如下(设 Ai+1、Bi+1 、Ci+1 、Di+1 为第 +1个时钟周期时打入寄存器的值):
以一下是每轮中用到的四个非线性函数(每轮一个)。
常数ti可以如下选择:在第i步中,ti是4294967296*abs(sin(i))的整数部分,i的单位是弧度。Wi是512位消息分组中的一个,Si是每次循环移位的次数。对每次而言也是固定的常数。
(5)结果输出:所有64步完成之后,将第64步的输出加到四个初始化变量上作为新的初始化变量,进行下一个512比特分组的运算,直到所有分组处理完毕,单次操作图如下:
图1. MD5算法单步操作图
3 算法优化
由上图可以看到,硬件实现时,MD5算法每一步操作中的关键路径在于B的求取(其他三个变量都是直接传递),这个关键路径包括了四个模 232加法运算、三输入变量的逻辑运算、"两个查找表运算及一个循环左移运算,而在FPGA设计中,加法运算最为耗时,四个加法运算至少需要三个加法器级联完成,加法运算严重制约了整个操作的速度,可见要加快算法运行速度就必须在简化这一关键路径上下工夫,经过观察我们发现,在
中 对每个周期都是已知的常数,是输入的512比特的一个32位分组,这样,在512比特输入初始化完成后,也可看作固定常数,
Ai是第i时钟周期里寄存器D 的值,而 Di的值又是第i-1周期里的Ci-1 ,即Ai 的`值是第i-1周期里Ci-1的值。
若在第i周期设中间寄存器变量 ,并令
那么在第i+1周期,
就可以表示为
操作就可以用下面几个式子代替:
其中, Ai+1没有参与任何运算,因此上式可以接着化简为
这样一来,原来一个周期内需要完成三级加法和相应的组合逻辑,现在只需要完成两级加法和部分组合逻辑就行了,大大提高了算法速度,只要在运算开始时加-个周期的初始化即可,简化后的系统框图如下:
图2. 改进后的单步操作图
4 结果比较
由上文中的算法分析部分不难看出,传统的实现方式关键路径是3级32比特加法器延迟和组合逻辑的延迟,而改进的实现方式减少了一级加法器的延迟,并把组合逻辑的延迟分散到不同路径上,因此,采用改进的实现方式大约可以将速度提高到原来的1.5倍左右。同时,为了实现数据的初始化,需要提前一个周期计算出寄存器A的值,因此整个算法的实现需要65个周期。我们采用 VerilogHDL 描述,选择Altera Stratix II EP2S15F672C5 FBGA芯片,在QuartusII6.0上验证通过。由于在FPGA中,连线延时也很关键,而这部分延时不能像加法延时那样通过预先计算并存储在寄存器中来消除一部分,所以实际的MD5改进算法与传统型相比较,速度的提高约为1.3,资源方面由于只是增加了一个时钟节拍,寄存器数量和组合逻辑并没有增加,所以改进型在资源方面和传统型相当。下表为算法改进前后在资源、频率、流量上的比较。
表1. 改进前后资源比较
5 结束语
由表1可见,改进型MD5算法实现,使用的资源并没有明显增加,但速度的改善十分明显,基本实现了用较少的资源得到较高速率的目标,证明了结构的正确性和合理性。实验结果也说明,这种利用寄存器来减少加法器级联从而减少关键路径的实现方法也可用于一般的FPGA硬件设计中。
参考文献
[1] R.Rivest. The MD5 Message-Digest Algorithm,RFC1321 1992。
[2] Jarvinen K, Tommiska M,Skytta J.Hardware implementation analysis of the MD5 hash algorithm.System Sciences,2005.HICSS’05.Proceedings of the 38th Annual Hawaii International conference on 03-06 Jan.2005:298
[3] Bruce Schneier. 应用密码学.北京:机械工业出版社,2000:188~194
[4] William Stallings. 密码编码学与网络安全:原理与实践.北京:电子工业出版社,2001: 216~222。
[5] 夏宇闻.Verilog 数字系统设计教程.航空航天大学出版社,2005
;③ 用verilog语言实现FPGA的循环码编码器设计
摘 要
随着电子技术的发展,具有防盗报警等功能的电子密码锁代替密码量少、安全性差的机械式密码锁已是必然趋势。电子密码锁与普通机械锁相比,具有许多独特的优点:保密性好,防盗性强,可以不用钥匙,记住密码即可开锁等。目前使用的电子密码锁大部分是基于单片机技术,以单片机为主要器件,其编码器与解码器的生成为软件方式。在实际应用中,由于程序容易跑飞,系统的可靠性能较差。
本文主要阐述了一种基于现场可编程门阵列FPGA器件的电子密码锁的设计方法。用FPGA器件构造系统,所有算法完全由硬件电路来实现,使得系统的工作可靠性大为提高。由于FPGA具有现场可编程功能,当设计需要更改时,只需更改FPGA中的控制和接口电路,利用EDA工具将更新后的设计下载到FPGA中即可,无需更改外部电路的设计,大大提高了设计的效率。因此,采用FPGA开发的数字系统,不仅具有很高的工作可靠性,而且升级也极其方便。
本文采用EDA技术,利用Quartus II工作平台和硬件描述语言,设计了一种电子密码锁,并通过一片FPGA芯片实现。
关键词:电子密码锁;FPGA;硬件描述语言;EDA
目 录
1 绪 论 1
1.1 国内外现状及其发展 1
1.2 电子密码锁的原理 2
1.3 电子密码锁的系统简介 4
1.4 系统设计要求 4
1.5 本课题的研究目的和意义 5
2 现场可编程门阵列FPGA 6
2.1 FPGA的基本结构 6
2.2 FPGA的优点 10
2.3 FPGA的设计流程 11
2.4 自顶向下设计法 17
2.5用模块化设计FPGA 18
3 VHDL硬件描述语言 20
3.1 VHDL语言的基本结构 20
3.2 结构体的描述方式 21
3.3 自上而下(TOP DOWN)的设计方法 22
4 电子密码锁的设计与仿真 24
4.1 硬件设备 24
4.2 几个主要功能模块的设计 25
4.3 计算机仿真 32
结 束 语 38
参考文献 39
附录1英文原文 41
附录2中文译文 50
附录3源程序 57
1.1 国内外现状及其发展
随着人们生活水平的提高和安全意识的加强,对安全的要求也就越来越高。锁自古以来就是把守护门的铁将军,人们对它要求甚高,既要安全可靠的防盗,又要使用方便,这也是制锁者长期以来研制的主题。随着电子技术的发展,各类电子产品应运而生,电子密码锁就是其中之一。据有关资料介绍,电子密码锁的研究从20世纪30年代就开始了,在一些特殊场所早就有所应用。这种锁是通过键盘输入一组密码完成开锁过程。研究这种锁的初衷,就是为提高锁的安全性。由于电子锁的密钥量(密码量)极大,可以与机械锁配合使用,并且可以避免因钥匙被仿制而留下安全隐患。电子锁只需记住一组密码,无需携带金属钥匙,免除了人们携带金属钥匙的烦恼,而被越来越多的人所欣赏。电子锁的种类繁多,例如数码锁,指纹锁,磁卡锁,IC卡锁,生物锁等。但较实用的还是按键式电子密码锁。
20世纪80年代后,随着电子锁专用集成电路的出现,电子锁的体积缩小,可靠性提高,成本较高,是适合使用在安全性要求较高的场合,且需要有电源提供能量,使用还局限在一定范围,难以普及,所以对它的研究一直没有明显进展。
目前,在西方发达国家,电子密码锁技术相对先进,种类齐全,电子密码锁已被广泛应用于智能门禁系统中,通过多种更加安全,更加可靠的技术实现大门的管理。在我国电子锁整体水平尚处于国际上70年代左右,电子密码锁的成本还很高,市场上仍以按键电子锁为主,按键式和卡片钥匙式电子锁已引进国际先进水平,现国内有几个厂生产供应市场。但国内自行研制开发的电子锁,其市场结构尚未形成,应用还不广泛。国内的不少企业也引进了世界上先进的技术,发展前景非常可观。希望通过不断的努力,使电子密码锁在我国也能得到广泛应用[1]。
目前使用的电子密码锁大部分是基于单片机技术,以单片机为主要器件,其编码器与解码器的生成为软件方式[2]。在实际应用中,由于程序容易跑飞,系统的可靠性能较差。基于现场可编程逻辑门阵列FPGA器件的电子密码锁,用FPGA器件构造系统,所有算法完全由硬件电路来实现,使得系统的工作可靠性大为提高。由于FPGA具有现场可编程功能,当设计需要更改时,只需更改FPGA中的控制和接口电路,利用EDA工具将更新后的设计下载到FPGA中即可,无需更改外部电路的设计,大大提高了设计的效率。
1.3 电子密码锁的系统简介
通用的电子密码锁主要由三个部分组成:数字密码输入电路、密码锁控制电路和密码锁显示电路。
(1) 密码锁输入电路包括时序产生电路、键盘扫描电路、键盘弹跳消除电路、键盘译码电路等几个小的功能电路。
(2)密码锁控制电路包括按键数据的缓冲存储电路,密码的清除、变更、存储、激活电锁电路(寄存器清除信号发生电路),密码核对(数值比较电路),解锁电路(开/关门锁电路)等几个小的功能电路。
(3)密码显示电路主要将显示数据的BCD码转换成相对应的编码。如,若选用七段数码管显示电路,主要将待显示数据的BCD码转换成数码器的七段显示驱动编码[4]。
1.4 系统设计要求
设计一个具有较高安全性和较低成本的通用电子密码锁,具体功能要求如下:
(1)数码输入:每按下一个数字键,就输入一个数值,并在显示器上的显示出该数值,同时将先前输入的数据依序左移一个数字位置。
(2)数码清除:按下此键可清除前面所有的输入值,清除为“0000”。
(3)密码更改:按下此键时会将目前的数字设定成新的密码。
(4)激活电锁:按下此键可将密码锁上锁。
(5)解除电锁:按下此键会检查输入的密码是否正确,密码正确即开锁。
1.5 本课题的研究目的和意义
随着人们生活水平的提高,对家庭防盗技术的要求也是越来越高,传统的机械锁由于其构造的简单,被撬的事件屡见不鲜,电子锁由于其保密性高,使用灵活性好,安全系数高,受到了广大用户的欢迎。现在市场上主要是基于单片机技术的电子密码锁,但可靠性较差。FPGA即现场可编程门阵列,它是在PAL、GAL、EPLD等可编程器件的基础上进一步发展的产物,是一种超大规模集成电路,具有对电路可重配置能力。通常FPGA都有着上万次的重写次数,也就是说现在的硬件设计和软件设计一样灵活、方便。相对于基于单片机技术的电子密码锁,用FPGA器件来构成系统,可靠性提高,并且由于FPGA具有的现场可编程功能,使得电子密码锁的更改与升级更为方便简单[3]。
通过本次设计掌握FPGA系统设计的方法,熟悉FPGA设计的相关软件,以及硬件描述语言的使用,了解电子密码锁的系统构成,利用FPGA实现电子密码锁的设计与实现,可以加深自己对所学专业的认识,关联知识,增强自己的动手能力,积累实践经验,为以后的工作打好基础。
参考文献
[1] 李连华.基于FPGA的电子密码锁设计.中国科技信息,2006,(01):64
[2] 许琦.基于FPGA的电子密码锁的设计.科技信息,2006,(10):240-241
[3] 王卫兵,刘克刚,朱秋萍.用FPGA的电子密码锁.电子技术,2005,(01):26-28
[4] 赵益丹,徐晓林,周振峰.电子密码锁的系统原理、设计程序及流程图.嘉兴学院学报,2003,15(S1):103-105
[5] 陆重阳,卢东华.FPGA技术及其发展趋势.微电子技术,2003,(01):5-7
[6] 王晓勇.FPGA的基本原理及运用.舰船电子工程,2005,(02):82-85
[7] 程耀林.FPGA的系统设计方法解析.现代电子技术,2005,(19):90-93
[8] K. Benkrid, A. Benkrid and S. Belkacemi .Efficient FPGA hardware development: A multi-language approach .Journal of Systems Architectur -e, 2007(04):184-209
[9] Altera, Novas Team for FPGA Visibility Enhancement .Electronic News (North America).2006,(11):12
[10] 张忠.自顶向下的FPGA设计.电子产品世界,1998,(11):33-34,72
[11] 路而红.专用集成电路设计与电子设计自动化.北京:清华大学出版社,2004:162-181,239-280,329-332
[12] 罗杰,康华光.两种硬件描述语言VHDL/Verilog的发展及其应用.电气电子教学学报, 2002,24(04):1-5
[13] 曹建国, 王威, 王丹. 一种基于VHDL的电子密码锁的设计与实现.沈阳大学学报 , 2006,18(04):77-79
[14] 谭会生,瞿遂春.EDA技术综合应用实例与分析.西安:西安电子科技大学出版社,2004.1-42,64-85
[15] 梁丽.电子密码锁的计算机仿真设计.计算机仿真,2005,22(02):218-220
④ FPGA现在学起来怎么样难不需要了解哪些基础课程
FPGA学习重点
1. 看代码,建模型
只有在脑海中建立了一个个逻运祥模辑模型,理解FPGA内部逻辑结构实现的基础,才能明白为什么写Verilog和写C整体思路是不一样的,才能理解顺序执行语言和并行执行语言的设计方法上的差异。在看到一段简单程序的时候应该想到是什么样的功能电路。2. 用数学思维来简化设计逻辑
学习FPGA不仅逻辑思维很重要,好的数学思维也能让你的设计化繁为简,所以啊,那些看见高数就头疼的童鞋需要重视一下这门课哦。举个简单的例子,比如有两个32bit的数据X[31:0]与Y[31:0]相乘。当然,无论Altera还是Xilinx都有现成的乘法器IP核可以调用,这也是最简单的方法,但是两个32bit的乘法器将耗费大量的资源。那么有没有节省资源,又不太复杂的方式来实现呢?我们可以稍做修改:将X[31:0]拆成两部分X1[15:0]和X2[15:0],令X1[15:0]=X[31:16],X2[15:0]=X[15:0],则X1左移16位后与X2相加可以得到X;同样将Y[31:0]拆成两部分宴者Y1[15:0]和Y2[15:0],令 Y1[15:0]=Y[31:16],Y2[15:0]=Y[15:0],则Y1左移16位后与Y2相加可以得到Y,则X与Y的相乘可以转化为X1和X2 分别与Y1和Y2相乘,这样一个32bit*32bit的乘法运算转换成了四个16bit*16bit的乘法运算和三个32bit的加法运算。转换后的占用资源将会减少很多,有兴趣的童鞋,不妨综合一下看看,看看两者差多少。3. 时钟与触发器的关系
“时钟是时序电路的控制者”这句话太经典了,可以说是FPGA设计的圣言。FPGA的设计主要是以时序电路为主,因为组合逻辑电路再怎么复杂也变不出太多花样,理解起来也不没太多困难。但是时序电路就不同了,它的所有动作都是在时钟一拍一拍的节奏下转变触发,可以说时钟就是整个电路的控制者,控制不好,电路功能就会混乱。打个比方,时钟就相当于人体的心脏,它每一次的跳动就是触发一个 CLK,向身体的各个器官供血,维持着机体的正常运作,每一个器官体统正常工作少不了组织细胞的构成,那么触发器就可以比作基本单元组织细胞。
时序逻辑电路的时钟是控制时序逻辑电路旁缓状态转换的“发动机”,没有它时序逻辑电路就不能正常工作。因为时序逻辑电路主要是利用触发器存储电路的状态,而触发器状态变换需要时钟的上升或下降沿,由此可见时钟在时序电路中的核心作用。最后简单说一下体会吧,归结起来就是多实践、多思考、多问。实践出真知,看100遍别人的方案不如自己去实践一下。实践的动力一方面来自兴趣,一方面来自压力。有需求会容易形成压力,也就是说最好能在实际的项目开发中锻炼,而不是为了学习而学习。为什么你会觉得FPGA难学?
1. 不熟悉FPGA的内部结构
FPGA为什么是可以编程的?恐怕很多初学者不知道,他们也不想知道。因为他们觉得这是无关紧要的。他们潜意识的认为可编程嘛,肯定就是像写软件一样啦。软件编程的思想根深蒂固,看到Verilog或者VHDL就像看到C语言或者其它软件编程语言一样。一条条的读,一条条的分析。
拒绝去了解为什么FPGA是可以编程的,不去了解FPGA的内部结构,要想学会FPGA 恐怕是天方夜谭。那么FPGA为什么是可以“编程”的呢?首先来了解一下什么叫“程”。其实 “程”只不过是一堆具有一定含义的01编码而已。编程,其实就是编写这些01编码。只不过我们现在有了很多开发工具运算或者是其它操作。所以软件是一条一条的,通常都不是直接编写这些01编码,而是以高级语言的形式来编写,最后由开发工具转换为这种01编码而已。对于软件编程而言,处理器会有一个专门的译码电路逐条把这些01编码翻译为各种控制信号,然后控制其内部的电路完成一个个的读,因为软件的操作是一步一步完成的。
而FPGA的可编程,本质也是依靠这些01编码实现其功能的改变,但不同的是FPGA之所以可以完成不同的功能,不是依靠像软件那样将01编码翻译出来再去控制一个运算电路,FPGA里面没有这些东西。FPGA内部主要三块:可编程的逻辑单元、可编程的连线和可编程的IO模块。
可编程的逻辑单元
其基本结构某种存储器(SRAM、 FLASH等)制成的4输入或6输入1输出的“真值表”加上一个D触发器构成。任何一个4输入1输出组合逻辑电路,都有一张对应的“真值表”,同样的如果用这么一个存储器制成的4输入1输出的“真值表”,只需要修改其“真值表”内部值就可以等效出任意4输入1输出的组合逻辑,这些“真值表”内部值就是那些01编码。
如果要实现时序逻辑电路怎么办?任何的时序逻辑都可以转换为组合逻辑+D触发器来完成。但这毕竟只实现了4输入1输出的逻辑电路而已,通常逻辑电路的规模那是相当的大。可编程连线
那怎么办呢?这个时候就需要用到可编程连线了。在这些连线上有很多用存储器控制的链接点,通过改写对应存储器的值就可以确定哪些线是连上的而哪些线是断开的。这就可以把很多可编程逻辑单元组合起来形成大型的逻辑电路。
可编程的IO
任何芯片都必然有输入引脚和输出引脚。有可编程的IO可以任意的定义某个非专用引脚(FPGA中有专门的非用户可使用的测试、下载用引脚)为输入还是输出,还可以对IO的电平标准进行设置。
总归一句话,FPGA之所以可编程是因为可以通过特殊的01代码制作成一张张 “真值表”,并将这些“真值表”组合起来以实现大规模的逻辑功能。不了解FPGA内部结构,就不能明白最终代码如何变到FPGA里面去的,也就无法深入的了解如何能够充分运用FPGA。现在的FPGA,不单单是有前面讲的那三块,还有很多专用的硬件功能单元,如何利用好这些单元实现复杂的逻辑电路设计,是从菜鸟迈向高手的路上必须要克服的障碍。而这一切,还是必须先从了解FPGA内部逻辑及其工作原理做起。
2. 错误理解HDL语言,怎么看都看不出硬件结构
HDL语言的英语全称是:Hardware Deion Language,注意这个单词Deion,而不是Design。老外为什么要用Deion这个词而不是Design呢?因为HDL确实不是用用来设计硬件的,而仅仅是用来描述硬件的。
描述这个词精确地反映了HDL语言的本质,HDL语言不过是已知硬件电路的文本表现形式而已,只是将以后的电路用文本的形式描述出来而已。而在编写语言之前,硬件电路应该已经被设计出来了。语言只不过是将这种设计转化为文字表达形式而已。
硬件设计也是有不同的抽象层次,每一个层次都需要设计。最高的抽象层次为算法级、然后依次是体系结构级、寄存器传输级、门级、物理版图级。
使用HDL的好处在于我们已经设计好了一个寄存器传输级的电路,那么用HDL描述以后转化为文本的形式,剩下的向更低层次的转换就可以让EDA工具去做了,这就大大的降低了工作量。这就是可综合的概念,也就是说在对这一抽象层次上硬件单元进行描述可以被EDA工具理解并转化为底层的门级电路或其他结构的电路。在FPGA设计中,就是在将这以抽象层级的意见描述成HDL语言,就可以通过FPGA开发软件转化为上一点中所述的FPGA内部逻辑功能实现形式。HDL也可以描述更高的抽象层级如算法级或者是体系结构级,但目前受限于EDA软件的发展,EDA软件还无法理解这么高的抽象层次,所以HDL描述这样抽象层级是无法被转化为较低的抽象层级的,这也就是所谓的不可综合。
所以在阅读或编写HDL语言,尤其是可综合的HDL,不应该看到的是语言本身,而是要看到语言背后所对应的硬件电路结构。3. FPGA本身不算什么,一切皆在FPGA之外
FPGA是给谁用的?很多学校是为给学微电子专业或者集成电路设计专业的学生用的,其实这不过是很多学校受资金限制,买不起专业的集成电路设计工具而用FPGA工具替代而已。其实FPGA是给设计电子系统的工程师使用的。这些工程师通常是使用已有的芯片搭配在一起完成一个电子设备,如基站、机顶盒、视频监控设备等。当现有芯片无法满足系统的需求时,就需要用FPGA来快速的定义一个能用的芯片。前面说了,FPGA里面无法就是一些“真值表”、触发器、各种连线以及一些硬件资源,电子系统工程师使用FPGA进行设计时无非就是考虑如何将这些以后资源组合起来实现一定的逻辑功能而已,而不必像IC设计工程师那样一直要关注到最后芯片是不是能够被制造出来。
本质上和利用现有芯片组合成不同的电子系统没有区别,只是需要关注更底层的资源而已。要想把FPGA用起来还是简单的,因为无非就是那些资源,在理解了前面两点再搞个实验板,跑跑实验,做点简单的东西是可以的。而真正要把FPGA用好,那光懂点FPGA知识就远远不够了。因为最终要让FPGA里面的资源如何组合,实现何种功能才能满足系统的需要,那就需要懂得更多更广泛的知识。4. 数字逻辑知识是根本
无论是FPGA的哪个方向,都离不开数字逻辑知识的支撑。FPGA说白了是一种实现数字逻辑的方式而已。如果连最基本的数字逻辑的知识都有问题,学习FPGA的愿望只是空中楼阁而已。数字逻辑是任何电子电气类专业的专业基础知识,也是必须要学好的一门课。
如果不能将数字逻辑知识烂熟于心,养成良好的设计习惯,学FPGA到最后仍然是雾里看花水中望月,始终是一场空的。以上四条只是我目前总结菜鸟们在学习FPGA时所最容易跑偏的地方,FPGA的学习其实就像学习围棋一样,学会如何在棋盘上落子很容易,成为一位高手却是难上加难。要真成为李昌镐那样的神一般的选手,除了靠刻苦专研,恐怕还确实得要一点天赋。荐读
1. 入门首先要掌握HDL(HDL=verilog+VHDL)
第一句话是:还没学数电的先学数电。然后你可以选择verilog或者VHDL,有C语言基础的,建议选择VHDL。因为verilog太像C了,很容易混淆,最后你会发现,你花了大量时间去区分这两种语言,而不是在学习如何使用它。当然,你思维能转得过来,也可以选verilog,毕竟在国内verilog用得比较多。接下来,首先找本实例抄代码。抄代码的意义在于熟悉语法规则和编译器(这里的编译器是硅编译器又叫综合器,常用的编译器有:Quartus、ISE、Vivado、Design Compiler 、Synopsys的VCS、iverilog、Lattice的Diamond、Microsemi/Actel的Libero、Synplify pro),然后再模仿着写,最后不看书也能写出来。编译完代码,就打开RTL图,看一下综合出来是什么样的电路。HDL是硬件描述语言,突出硬件这一特点,所以要用数电的思维去思考HDL,而不是用C语言或者其它高级语言,如果不能理解这句话的,可以看《什么是硬件以及什么是软件》。在这一阶段,推荐的教材是《Verilog传奇》、《Verilog HDL高级数字设计》或者是《用于逻辑综合的VHDL》。不看书也能写出个三段式状态机就可以进入下一阶段了。此外,你手上必须准备Verilog或者VHDL的官方文档,《verilog_IEEE官方标准手册-2005_IEEE_P1364》、《IEEE Standard VHDL Language_2008》,以便遇到一些语法问题的时候能查一下。2. 独立完成中小规模的数字电路设计
现在,你可以设计一些数字电路了,像交通灯、电子琴、DDS等等,推荐的教材是夏老《Verilog 数字系统设计教程》(第三版)。在这一阶段,你要做到的是:给你一个指标要求或者时序图,你能用HDL设计电路去实现它。这里你需要一块开发板,可以选Altera的cyclone IV系列,或者Xilinx的Spantan 6。
还没掌握HDL之前千万不要买开发板,因为你买回来也没用。这里你没必要每次编译通过就下载代码,咱们用modelsim仿真(此外还有QuestaSim、NC verilog、Diamond的Active-HDL、VCS、Debussy/Verdi等仿真工具),如果仿真都不能通过那就不用下载了,肯定不行的。在这里先掌握简单的testbench就可以了。推荐的教材是《WRITING TESTBENCHES Functional Verification of HDL Models》。3. 掌握设计方法和设计原则
你可能发现你综合出来的电路尽管没错,但有很多警告。这个时候,你得学会同步设计原则、优化电路,是速度优先还是面积优先,时钟树应该怎样设计,怎样同步两个异频时钟等等。
推荐的教材是《FPGA权威指南》、《IP核芯志-数字逻辑设计思想》、《Altera FPGA/CPLD设计》第二版的基础篇和高级篇两本。学会加快编译速度(增量式编译、LogicLock),静态时序分析(timequest),嵌入式逻辑分析仪(signaltap)就算是通关了。如果有不懂的地方可以暂时跳过,因为这部分还需要足量的实践,才能有较深刻的理解。4. 学会提高开发效率
因为Quartus和ISE的编辑器功能太弱,影响了开发效率。所以建议使用Sublime text编辑器中代码片段的功能,以减少重复性劳动。Modelsim也是常用的仿真工具,学会TCL/TK以编写适合自己的DO文件,使得仿真变得自动化,推荐的教材是《TCL/TK入门经典》。
你可能会手动备份代码,但是专业人士都是用版本控制器的,所以,为了提高工作效率,必须掌握GIT。文件比较器Beyond Compare也是个比较常用的工具。此外,你也可以使用System Verilog来替代testbench,这样效率会更高一些。如果你是做IC验证的,就必须掌握System Verilog和验证方法学(UVM)。推荐的教材是《Writing Testbenches using SystemVerilog》、《The UVM Primer》、《System Verilog1800-2012语法手册》。掌握了TCL/TK之后,可以学习虚拟Jtag(ISE也有类似的工具)制作属于自己的调试工具,此外,有时间的话,最好再学个python。脚本,意味着一劳永逸。5. 增强理论基础
这个时候,你已经会使用FPGA了,但是还有很多事情做不了(比如,FIR滤波器、PID算法、OFDM等),因为理论没学好。我大概地分几个方向供大家参考,后面跟的是要掌握的理论课。信号处理 —— 信号与系统、数字信号处理、数字图像处理、现代数字信号处理、盲信号处理、自适应滤波器原理、雷达信号处理
接口应用 —— 如:UART、SPI、IIC、USB、CAN、PCIE、Rapid IO、DDR、TCP/IP、SPI4.2(10G以太网接口)、SATA、光纤、DisplayPort
无线通信 —— 信号与系统、数字信号处理、通信原理、移动通信基础、随机过程、信息论与编码
CPU设计 —— 计算机组成原理、单片机、计算机体系结构、编译原理
仪器仪表 —— 模拟电子技术、高频电子线路、电子测量技术、智能仪器原理及应用
控制系统 —— 自动控制原理、现代控制理论、过程控制工程、模糊控制器理论与应用
压缩、编码、加密 —— 数论、抽象代数、现代编码技术、信息论与编码、数据压缩导论、应用密码学、音频信息处理技术、数字视频编码技术原理现在你发现,原来FPGA会涉及到那么多知识,你可以选一个感兴趣的方向,但是工作中很有可能用到其中几个方向的知识,所以理论还是学得越多越好。如果你要更上一层,数学和英语是不可避免的。6. 学会使用MATLAB仿真
设计FPGA算法的时候,多多少少都会用到MATLAB,比如CRC的系数矩阵、数字滤波器系数、各种表格和文本处理等。此外,MATLAB还能用于调试HDL(用MATLAB的计算结果跟用HDL算出来的一步步对照,可以知道哪里出问题)。推荐的教材是《MATLAB宝典》和杜勇的《数字滤波器的MATLAB与FPGA实现》。7. 图像处理
Photoshop
花一、两周的时间学习PS,对图像处理有个大概的了解,知道各种图片格式、直方图、色相、通道、滤镜、拼接等基本概念,并能使用它。这部分是0基础,目的让大家对图像处理有个感性的认识,而不是一上来就各种各样的公式推导。推荐《Photoshop CS6完全自学教程》。基于MATLAB或OpenCV的图像处理
有C/C++基础的可以学习OpenCV,否则的话,建议学MATLAB。这个阶段下,只要学会简单的调用函数即可,暂时不用深究实现的细节。推荐《数字图像处理matlab版》、《学习OpenCV》。图像处理的基础理论
这部分的理论是需要高数、复变、线性代数、信号与系统、数字信号处理等基础,基础不好的话,建议先补补基础再来。看不懂的理论也可以暂时先放下,或许学到后面就自然而然地开窍了。推荐《数字图像处理》。基于FPGA的图像处理
把前面学到的理论运用到FPGA上面,如果这时你有前面第七个阶段的水平,你将轻松地独立完成图像算法设计(图像处理是离不开接口的,上面第五个阶段有讲)。推荐《基于FPGA的嵌入式图像处理系统设计》、《基于FPGA的数字图像处理原理及应用》。进一步钻研数学。要在算法上更上一层,必然需要更多的数学,所以这里建议学习实分析、泛涵分析、小波分析等。
⑤ FPGA怎么开始学
学习步骤:
1,计算机必不可少。可以选择安装quartusII或者ISE软件。这是必备的软件环境。
2、熟悉verilog语言或者vhdl语言 ,熟练使用quartusII或者ISE软件。
3、设计一个小代码,下载到目标板看看结果。
4、设计稍微复杂的代码,下载到目标板看看结果。
5、设计复杂的代码,下载到目标板看看结果。
6、设计高速接口,譬如ddr2或者高速串行接口
7、设计一个复杂的协议,譬如USB、PCIexpress、图像编解码等。
8、学习再学习,知道“学无止境,山外有山”。
注意事项:第一步:学习了解FPGA结构,FPGA到底是什么东西,芯片里面有什么,不要开始就拿个开发板照着别人的东西去编程。
第二步:掌握FPGA设计的流程。了解每一步在做什么,为什么要那么做。
第三步:开始学习代码了。不要一开始就走入误区。
第四步:template很重要。能不能高效利用FPGA资源,一是了解fpga结构,二是了解欲实现的逻辑功能和基本机构,三是使用正确的模板。
总结:理解时序,逻辑是一拍一拍的东西,在设计初期想的不是很清楚的时候可以画画时序图,这样思路会更加的清晰,还有就是仿真很重要,不要写完程序就去往FPGA中去加载,首先要仿真,尤其是对比较大型一点的程序,想象自己是在做asic,是没有二次机会的,所以一定要把仿真做好。