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相乘,这样一个32bit32bit的乘法运算转换成了四个16bit16bit的乘法运算和三个32bit的加法运算。转换后的占用资源将会减少很多,有兴趣的童鞋,不妨综合一下看看,看看两者差多少。
3. 时钟与触发器的关系
“时钟是时序电路的控制者”这句话太经典了,可以说是FPGA设计的圣言。FPGA的设计主要是以时序电路为主,因为组合逻辑电路再怎么复杂也变不出太多花样,理解起来也不没太多困难。但是时序电路就不同了,它的所有动作都是在时钟一拍一拍的节奏下转变触发,可以说时钟就是整个电路的控制者,控制不好,电路功能就会混乱。
打个比方,时钟就相当于人体的心脏,它每一次的跳动就是触发一个 CLK,向身体的各个器官供血,维持着机体的正常运作,每一个器官体统正常工作少不了组织细胞的构成,那么触发器就可以比作基本单元组织细胞。
时序逻辑电路的时钟是控制时序逻辑电路状态转换的“发动机”,没有它时序逻辑电路就不能正常工作。因为时序逻辑电路主要是利用触发器存储电路的状态,而触发器状态变换需要时钟的上升或下降沿,由此可见时钟在时序电路中的核心作用。
FPGA开发笼统的说可以分为两个方向,一个是接口方向、一个是算法方向。
接口方向
接口方向可不是简单的uart、IIC、SPI等这些简单接口,这些东西不足以支撑一个方向,大部分都是基于serdes的高速复杂接口,例如PCIE、SATA等。还有以太网,甚至可能不太复杂的SDRAM控制接口。
这些接口简单么? 简单,不是都有IP核可以调用么,IP核是个好东西,节省了我们大部分的时间,要不自己写一个试试?感觉impossible啊,看看那一堆复杂的协议,光用ip核都一大堆问题了,还敢夸口自己写,
要是没人带,很难自己搞的出来。这也是我害怕搞接口的原因。之前公司有一个华为的大牛,没有用厂家的IP核,说这个收费的IP核要多少W美刀,硬是自己写了一个,我是一直都很佩服他的,因为这种接口如此的复杂,光理解那些协议还是英文的,我都不知道能不能理解。也许是他之前在华为搞过这个接口,但早期华为出来的人,估计大概是(03年~13年)在华为吧,真的是有很厉害,现在的华为据说分的特别细,可能一个人就负责一个模块,好几年都是这样,把细节做到极致,但是人就螺丝钉化了,有好有不好吧。
因为工作的原因,现在已经接触到了serdes以及基于serdes的jesd和cpri协议等,可以说接口方面也算是入了门的吧,但实际上也都是IP核来实现的,光ip核调试起来有时候都要磨很久了。甚至有时候光一个小问题磨你一两个月都很常见
因为接口方向我可能是入门水准,也就不说太多了。
总之接口方向就是 复杂的接口+复杂的协议,要阅读海量的数据手册,跟硬件专业亲密的扯皮加配合,踩过无数的坑,方能略有小成
算法方向
接下来说说算法方向,一般来说以算法作为一个方向,那么这个算法整体来说是非常复杂的。以导航的定位解算来举例。
导航的定位解算包括:中频信号搬频到基带、进行信号的捕获(涉及相关运算、FFT等)、信号的跟踪(数字锁频环、数字锁相环、观测量提取、电文的提取)、电文提取(信道解码、解交织、位同步、帧同步、电文解析)、定位解算(伪距计算输出、载波相位输出,最小二乘法算法,星历参数计算,统称PVT解算(位置、速度、时间) )
这么多算法全部整合在一起,需要进行充分的验证,如果只是用类似modelsim来仿真,那速度真是慢的想哭。那么我们需要更高级的方法,我们需要一个定点模型,matlab定点模型或者C定点模型。对于某些要做芯片的工程,一般是要做成C模型,C模型的效率比matlab更高,虽然看起来matlab更简单直接
算法模型要做到什么程度呢,最理想的就是要做到和modelsim仿真结果一模一样,无论是某些重要的中间结果还是最终结果,无论是数据流型的结果还是触发型的结果,都要完全的一模一样。因此算法模型的搭建会占用你大量的时间,但是一但搭建成功,则后面大部分验证都完全可以通过算法模型去仿真,不在需要在用modelsim进行仿真了,因为modelsim相对于matlab或者C模型来说,实在是太慢太不方便了。
之前在那家创业公司弄GPS导航信号接收处理,捕获部分是比较复杂的,100多个并行相关器进行短时相关+FFT的操作,我是花了很多时间用matlab做了完全一致的定点化模型,完成了之后,后面要改什么,或者要验证什么就非常方便了,因为我可以直接在matlab模型上进行验证了,无需通过跑modelsim,基本就知道其是否正确了
matlab做算法模型还比较好理解,但C做算法模型呢
以下这个这个例子,表示用C来实现GPS C/A码并且进行验证
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include “PrnGen.h”
#include “PrnInit.h”
#include “GPSPrnTable.h”
void main(void)
{
PrnGen PrnGen;
int i,j,prn;
int error = 0;
int CodeOutI[1023];
unsigned int SRegs[24];
unsigned int SBuffer[6];
// set 0 for GPS , G1 and G2 parallel, code length = 1023
SRegs[0] = (0x3a6 << 14) | 0x204;
SRegs[1] = 1023 << 14;
SRegs[2] = (0x3a6 << 14) | 0x204;
SRegs[3] = 1023 << 14;
// check GPS L1 C/A in CodeI
PrnGen.SetPoly(&(SettingRegs[0]));
for (prn=1; prn<=32; prn++)
{
SBuffer[0] = SBuffer[2] = CAPrnInit[prn];
SBuffer[4] = 0;
for(i=0;i<10;i++)
{
PrnGen.Reset();
PrnGen.LoadState(SBuffer);
for(j=0; j<1023; j++)
{
CodeOutI[j] = PrnGen.GetCodeI();
PrnGen.ShiftCodeI();
if (CodeOutI[j] != CAcode[prn-1][j])
{
error = 1;
printf(“error on prn%d bit%d!n”, prn, j);
}
}
PrnGen.DumpState(SBuffer);
}
}
if (error == 0)
printf(“C/A code test passed!n”);
system(“PAUSE”);
}
上面是模拟verilog实现的功能,其实虽然C和MATLAB是顺序执行的,但也是可以模拟verilog并行执行的,如下面就是模拟verilog的并行执行功能
while (1)
{
clkcnt = clkcnt +1;
delay_d3 =delay_d2;
delay_d2 = delay_d1;
delay_d1 = delay_in;
}
这个等效于verilog的下面语句
always @(POSedge clk)
begin
delay_d1 <= delay_in;
delay_d2 <=delay_d1;
delay_d3 <= delay_d2;
end
以上只是冰上一脚,以前接触过的大型工程,甚至要做芯片去流片的C算法模型非常的庞大
总结
如果以武功来描述这两个方向的关系,接口就是剑,算法是气。
剑是纷繁复杂的招数,华山剑法(JESD)、嵩山剑法(PCIE)、辟邪剑法(SATA),每一个都招式繁多,但每个招式都记录于剑谱(协议)只上,因为招式是死的,理论上只要有人手把手的教,基本都能学会。但事实上不会有人手把手的教,一般只有门派(公司)有什么才能学到什么,而且也不会有人手把手去交,老员工一般只是会稍加提点,大部分情况下要去自己勤加苦练。想学更多只能改投其他门派了,但投靠门派多了,可能各门武功都学艺不精了。
气是深厚内力的修为,紫霞神功(数字信号处理)、吸星大法(高等数学),这些东西只有口诀,完全根据自己的悟性才能练到多少重。想想当年高等数学都理解了不,数字信号处理、信号与系统都想得明白么,想不明白,有人教也没用,因为理解不了。第一家公司有一个清华的同事,人家理解LDCP编解码,人家理解的那一个快呀。我是半天都看不懂,因为我高等数学差呀。。。这真的跟智商有关系呀。
以上是一些粗鄙的认识,两个方向都不容易,接口需要对架构、协议做非常深的理解才能游刃有余,而且调接口是非常需要经验的,高手都是踩过无数的坑而来。算法实现首先需要一些理论功底,首先必须完全理解这个算法,然后算法实现的好坏优劣也跟你实现的方式有关。所以无论是练剑还是练气,练到极致那都是非常优秀的了。
没有回复内容