fpga笔试.docx
- 文档编号:8047486
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:22
- 大小:343.33KB
fpga笔试.docx
《fpga笔试.docx》由会员分享,可在线阅读,更多相关《fpga笔试.docx(22页珍藏版)》请在冰豆网上搜索。
fpga笔试
第一篇FPGA基础题
1.1.⑴结合Xilinx、Altera等公司的FPGA芯片,简要罗列一下FPGA内部的资源或专用模块,并简要说明这些资源的一些作用或用途。
(至少列出5项,越多越好)
⑵如果,对内部特定资源,曾有应用经历,结合个人理解和体验,简要说明初步的设计技巧或设计经验。
1.可编程输入输出单元(IOB)
可编程输入/输出单元简称I/O单元,是芯片与外界电路的接口部分,完成不同电气特性下对输入/输出信号的驱动与匹配要求,其示意结构如图1-2所示。
FPGA内的I/O按组分类,每组都能够独立地支持不同的I/O标准。
通过软件的灵活配置,可适配不同的电气标准与I/O物理特性,可以调整驱动电流的大小,可以改变上、下拉电阻。
目前,I/O口的频率也越来越高,一些高端的FPGA通过DDR寄存器技术可以支持高达2Gbps的数据速率。
外部输入信号可以通过IOB模块的存储单元输入到FPGA的内部,也可以直接输入FPGA内部。
当外部输入信号经过IOB模块的存储单元输入到FPGA内部时,其保持时间(HoldTime)的要求可以降低,通常默认为0。
为了便于管理和适应多种电器标准,FPGA的IOB被划分为若干个组(bank),每个bank的接口标准由其接口电压VCCO决定,一个bank只能有一种VCCO,但不同bank的VCCO可以不同。
只有相同电气标准的端口才能连接在一起,VCCO电压相同是接口标准的基本条件。
2.可配置逻辑块(CLB)
CLB是FPGA内的基本逻辑单元。
CLB的实际数量和特性会依器件的不同而不同,但是每个CLB都包含一个可配置开关矩阵,此矩阵由4或6个输入、一些选型电路(多路复用器等)和触发器组成。
开关矩阵是高度灵活的,可以对其进行配置以便处理组合逻辑、移位寄存器或RAM。
在Xilinx公司的FPGA器件中,CLB由多个(一般为4个或2个)相同的Slice和附加逻辑构成,每个CLB模块不仅可以用于实现组合逻辑、时序逻辑,还可以配置为分布式RAM和分布式ROM。
3.数字时钟管理模块(DCM)
业内大多数FPGA均提供数字时钟管理(Xilinx的全部FPGA均具有这种特性)。
Xilinx推出最先进的FPGA提供数字时钟管理和相位环路锁定。
相位环锁定能够提供精确的时钟综合,且能够降低抖动,并实现过滤功能。
4.嵌入式块RAM(BRAM)
大多数FPGA都具有内嵌的块RAM,这大大拓展了FPGA的应用范围和灵活性。
块RAM可被配置为单端口RAM、双端口RAM、内容地址存储器(CAM)以及FIFO等常用存储结构。
可以根据需要改变其位宽和深度,但要满足两个原则:
首先,修改后的容量(位宽深度)不能大于18k比特;其次,位宽最大不能超过36比特。
当然,可以将多片块RAM级联起来形成更大的RAM,此时只受限于芯片内块RAM的数量,而不再受上面两条原则约束。
5.丰富的布线资源
布线资源连通FPGA内部的所有单元,而连线的长度和工艺决定着信号在连线上的驱动能力和传输速度。
FPGA芯片内部有着丰富的布线资源,根据工艺、长度、宽度和分布位置的不同而划分为4类不同的类别。
第一类是全局布线资源,用于芯片内部全局时钟和全局复位/置位的布线;第二类是长线资源,用以完成芯片Bank间的高速信号和第二全局时钟信号的布线;第三类是短线资源,用于完成基本逻辑单元之间的逻辑互连和布线;第四类是分布式的布线资源,用于专有时钟、复位等控制信号线。
6.底层内嵌功能单元
内嵌功能模块主要指DLL(DelayLockedLoop)、PLL(PhaseLockedLoop)、DSP和CPU等软处理核(SoftCore)。
现在越来越丰富的内嵌功能单元,使得单片FPGA成为了系统级的设计工具,使其具备了软硬件联合设计的能力,逐步向SOC平台过渡。
DLL和PLL具有类似的功能,可以完成时钟高精度、低抖动的倍频和分频,以及占空比调整和移相等功能。
Xilinx公司生产的芯片上集成了DLL,Altera公司的芯片集成了PLL。
7.内嵌专用硬核
内嵌专用硬核是相对底层嵌入的软核而言的,指FPGA处理能力强大的硬核(HardCore),等效于ASIC电路。
为了提高FPGA性能,芯片生产商在芯片内部集成了一些专用的硬核。
例如:
为了提高FPGA的乘法速度,主流的FPGA中都集成了专用乘法器;为了适用通信总线与接口标准,很多高端的FPGA内部都集成了串并收发器(SERDES),可以达到数十Gbps的收发速度。
Xilinx公司的高端产品不仅集成了PowerPC、Miroblaze、Picoblaze系列CPU,还内嵌了DSPCore模块,Altera的高端产品集成了Nios,能够开发标准的DSP处理器及其相关应用,达到SOC的开发目的。
1.2⑴FPGA一般设计流程如何,画出对应的流程图?
⑵针对个人理解和实践,列出个人理解中的关键设计流程,并指出核心设计流程中的关键技术或注意事项。
(1)PGA一般设计流程:
(2)个人设计习惯流程
设计时应注意:
1.设计必须文档化。
要将设计思路,详细实现等写入文档,然后经过严格评审通过,后才能进行下一步的工作。
2.端口信号排列要统一,一个信号只占一行,最好按从哪个模块来到哪个模块去的关系排列。
3.信号的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。
4.一个模块尽量只用一个时钟,这里的一个模块是指一个module。
在多时钟域的设计中涉及到跨时钟的设计最好有专门一个模块做时钟的隔离。
这样做可以让综合器综合出更优的结果。
5.尽量在底层模块上做逻辑,在高层尽量做例化,顶层模块只到做例化,禁止出现任何胶连逻辑(gluelogic),哪怕仅仅对某个信号取反
6. 在FPGA的设计上禁止用纯组合逻辑产生latch。
7.一般来说,进入FPGA的信号必须先同步,所有模块的输出都要寄存器化,以提高工作频率,这对设计做到时序收敛也是极有好处的。
8.除非是低功耗设计,不然不要用门控时钟:
这会增加设计的不稳定性,在要用到门控时钟的地方,也要将门控时钟用时钟的下降沿打一拍再输出与时钟相与。
9.尽量不要用计数器分频后的信号做其它模块的时钟,而要用改成时钟使能的方式,否则这钟时钟满天飞的方式对设计的可靠性极为不利,也大大增加了静态时序分析的复杂性。
10.内部模块不能出现inout端口,如果需要,把inout端口拆分为一组input和output。
11.数据都十六进制或者二进制表示,且要标上位数。
这样做综合器综合出的结果较好。
12.对齐一律用空格键,避免用TAB键。
这样可以保证程序在其它机子上显示的格式一致,便于阅读。
1.3结合自己应用情况,对比Altera、Xilinx公司自主开发的综合工具和Synplicity公司的Synplify综合工具的优缺点?
并谈一谈自身的实践和体会。
1.4⑴FPGA开发中,是否需要进行仿真验证?
为什么?
有什么个人体会?
⑵一般采用怎样的仿真工具和仿真手段?
了解Testbench吗?
⑶什么是前仿真和后仿真?
能否根据自身经历,总结一下前仿真和后仿真的特点和不同之处?
(1)FPGA开发中需要进行仿真验证,以便快速找到程序逻辑或语法错误提高设计效率。
本人自己开发时就每写完一个模块是就用modelsim仿真验证,根据modelsim中的错误信息,很快便可定位到错误代码处,极大的缩短了开发周期。
(2)编写设计文档时我更习惯用用ISE或libero,编写完代码后可以直接,然后添加测试文件,编写Testbench文档,可直接调用modelsim仿真验证。
编写Testbench时,有时也要借助matlab,如测试需要特殊信号数据或带噪声的信号数据。
可由matlab产生并写入文件,让后再通过$readmemh,将文件数据导入到Testbench中作为激励源。
做稍复杂点的仿真时,先做前仿真,将仿真输出正确结果用$fdisplayh输出到文件保存,然后通过后综合布局布线后,做后仿真。
后仿时,将前仿数据导入Testbench,逐个与后仿输出数据比较,并设一标志位,标志前仿真和后仿真输出结果的异同,方便找错问题所在处。
或者将也可将后仿真输出的数据以文件形式存储,在matlab中比较结果,找出错误数据位置,在到到mdelsim中找到对应位置各变量参数分析问题,并修正。
(3)软环境中没有激励输入,也不会对设计的输出正确性进行评估。
此时便需要一种,模拟实际环境的输入激励和输出校验的一种“虚拟平台”的产生。
在这个平台上你可以对你的设计从软件层面上进行分析和校验,这个就是testbench。
第二篇FPGA基础理论题
2.1.比较下面两个代码,利用FF、Adder、Mux、Demux等元件画出对应的框图,并比较这两个设计的不同以及优劣?
(注意:
不要对加法器等进行细化处理,如加法可以利用进位链实现,只要利用现有模块,如DFF、Adder、减法器等)
(1)always@(AorBorCorD)
sum=sel?
(A+B):
(C+D)
(2)always@(AorBorCorD)
begin
switch0=sel?
A:
C;
switch1=sel?
B:
D;
end
sum=switch0+switch1;
问题1.上面的不同代码,画出对应的框图
问题2.上面的代码,反映了FPGA设计中的一个什么道理?
问题1.
问题2.
很明显第二种这几比第一种设计少一个加法器,资源消耗减少,说明一个好的设计可以减少资源的占用,提高资源的利用率。
2.2请分别写出两个8bit补码数的加法和乘法运算的Verilog模块。
(提示:
注意补码的处理,支持Verilog2001国际规范)
注意:
输入信号和输出信号都是补码表示的数。
moduleadder(A,B,SUM);
input[7:
0]A,B;
//inputcin;//cincout,overflow
output[7:
0]SUM;
//outputcout,overflow;
wire[6:
0]c;
//È«¼ÓÆ÷Âß¼·½³Ìʽ
assignSUM[0]=A[0]^B[0]^0,//cin,
c[0]=(A[0]&B[0])|(B[0]&0)|(A[0]&0);
assignSUM[1]=A[1]^B[1]^c[0],
c[1]=(A[1]&B[1])|(B[1]&c[0])|(A[1]&c[0]);
assignSUM[2]=A[2]^B[2]^c[1],
c[2]=(A[2]&B[2])|(B[2]&c[1])|(A[2]&c[1]);
assignSUM[3]=A[3]^B[3]^c[2],
c[3]=(A[3]&B[3])|(B[3]&c[2])|(A[3]&c[2]);
assignSUM[4]=A[4]^B[4]^c[3],
c[4]=(A[4]&B[4])|(B[4]&c[3])|(A[4]&c[3]);
assignSUM[5]=A[5]^B[5]^c[4],
c[5]=(A[5]&B[5])|(B[5]&c[4])|(A[5]&c[4]);
assignSUM[6]=A[6]^B[6]^c[5],
c[6]=(A[6]&B[6])|(B[6]&c[5])|(A[6]&c[5]);
assignSUM[7]=A[7]^B[7]^c[6];
//cout=(A[7]&B[7])|(B[7]&c[6])|(A[7]&c[6]);
//
//assignoverflow=cout^c[6];
endmodule
补码乘法器:
modulemul_8bit(multiplicand,multiplier,ValOut);//start
parameterwidth=8;
//inputstart;
input[7:
0]multiplicand;
input[7:
0]multiplier;
output[15:
0]ValOut;
wire[7:
0]mulD;
wire[7:
0]mulR;
wiresign1,sign2,sign3,sign4;
wireone1,one2,one3,one4;
wiretwo1,two2,two3,two4;
//·ûºÅsign=~A[2n+1]&(A[2n]|A[2n-1])£»sign±íʾ·ûºÅ룬µ±ÆäΪ1ʱ£¬Ôò²¼Ë¹±àÂëÈ¡Õý£»·´Ö®£¬È¡¸º¡£A[-1]²¹Áã¼´A[-1]=0
assignsign1=~mulR[1]&(mulR[0]|0);
assignsign2=~mulR[3]&(mulR[2]|mulR[1]);
assignsign3=~mulR[5]&(mulR[4]|mulR[3]);
assignsign4=~mulR[7]&(mulR[6]|mulR[5]);
//one;one=A[2n]^A[2n-1]£»Èôone=1,Ôò²¿·Ö»ýΪb£»·ñÔòΪ0¡£
assignone1=mulR[0]^0;
assignone2=mulR[2]^mulR[1];
assignone3=mulR[4]^mulR[3];
assignone4=mulR[6]^mulR[5];
//twotwo=(¡«A[2n+1]&A[2n]&A[2n-1])|(A[2n+1]&¡«A[2n]&¡«A[2n-1])£»ÈôtwoΪ1£¬Ôò²¿·Ö»ýΪ2b£»·ñÔòΪ0¡£
assigntwo1=(~mulR[1]&mulR[0]&0)|(mulR[1]&~mulR[0]&1);
assigntwo2=(~mulR[3]&mulR[2]&mulR[1])|(mulR[3]&~mulR[2]&~mulR[1]);
assigntwo3=(~mulR[5]&mulR[4]&mulR[3])|(mulR[5]&~mulR[4]&~mulR[3]);
assigntwo4=(~mulR[7]&mulR[6]&mulR[5])|(mulR[7]&~mulR[6]&~mulR[5]);
//·ûºÅÀ©Õ¹
wire[15:
0]temp;
assigntemp={{8{mulD[7]}},mulD[7:
0]};
//¼ÆËãÊä³ö
wire[15:
0]dat_w1,dat_w2,dat_w3,dat_w4;
//-2*B==(~(B<<1))+1;2B=(B<<1);
assigndat_w1=(two1)?
((sign1)?
{temp[14:
0],1'b0}:
(~{temp[14:
0],1'b0}+1'b1)):
((one1)?
((sign1)?
temp:
{~temp+1'b1}):
0);
assigndat_w2=(two2)?
((sign2)?
{temp[14:
0],1'b0}:
(~{temp[14:
0],1'b0}+1'b1)):
((one2)?
((sign2)?
temp:
{~temp+1'b1}):
0);
assigndat_w3=(two3)?
((sign3)?
{temp[14:
0],1'b0}:
(~{temp[14:
0],1'b0}+1'b1)):
((one3)?
((sign3)?
temp:
{~temp+1'b1}):
0);
assigndat_w4=(two4)?
((sign4)?
{temp[14:
0],1'b0}:
(~{temp[14:
0],1'b0}+1'b1)):
((one4)?
((sign4)?
temp:
{~temp+1'b1}):
0);
assignValOut=dat_w1+{dat_w2[13:
0],2'b00}+{dat_w3[11:
0],4'b0000}+{dat_w4[9:
0],6'b000000};
assignmulD=multiplicand;
assignmulR=multiplier;
endmodule
2.3FPGA资源共享:
查看下面代码,画出对应框图?
能否从资源共享角度,重新编写代码,采用一个乘法器实现下面代码相同的功能?
请写出相关代码
moduleresour_share(i_data,o_square);
parameterDATA_WIDTH=8;
parameterPRO_WIDTH=16;
input[DATA_WIDTH-1:
0]i_data;
output[PRO_WIDTH-1:
0]o_square;
wire[DATA_WIDTH-1:
0]data_bar;
assigndata_bar=~i_data+1'b1;
wire[DATA_WIDTH-1:
0]multi,multi_d;
assignmulti=(i_data[DATA_WIDTH-1])?
data_bar:
i_data;
assignmulti_d=(i_data[DATA_WIDTH-1])?
data_bar:
i_data;
mul_8bitmul(.multiplicand(multi_d),
.multiplier(multi),
.ValOut(o_square));
endmodule
modulemul_8bit(multiplicand,multiplier,ValOut);//start
parameterwidth=8;
//inputclk;
//inputreset;
//inputstart;
input[7:
0]multiplicand;
input[7:
0]multiplier;
output[15:
0]ValOut;
wire[7:
0]mulD;
wire[7:
0]mulR;
wiresign1,sign2,sign3,sign4;
wireone1,one2,one3,one4;
wiretwo1,two2,two3,two4;
//·ûºÅsign=~A[2n+1]&(A[2n]|A[2n-1])£»sign±íʾ·ûºÅ룬µ±ÆäΪ1ʱ£¬Ôò²¼Ë¹±àÂëÈ¡Õý£»·´Ö®£¬È¡¸º¡£A[-1]²¹Áã¼´A[-1]=0
assignsign1=~mulR[1]&(mulR[0]|0);
assignsign2=~mulR[3]&(mulR[2]|mulR[1]);
assignsign3=~mulR[5]&(mulR[4]|mulR[3]);
assignsign4=~mulR[7]&(mulR[6]|mulR[5]);
//one;one=A[2n]^A[2n-1]£»Èôone=1,Ôò²¿·Ö»ýΪb£»·ñÔòΪ0¡£
assignone1=mulR[0]^0;
assignone2=mulR[2]^mulR[1];
assignone3=mulR[4]^mulR[3];
assignone4=mulR[6]^mulR[5];
//two=(¡«A[2n+1]&A[2n]&A[2n-1])|(A[2n+1]&¡«A[2n]&¡«A[2n-1])£»ÈôtwoΪ1£¬Ôò²¿·Ö»ýΪ2b£»·ñÔòΪ0¡£
assigntwo1=(~mulR[1]&mulR[0]&0)|(mulR[1]&~mulR[0]&1);
assigntwo2=(~mulR[3]&mulR[2]&mulR[1])|(mulR[3]&~mulR[2]&~mulR[1]);
assigntwo3=(~mulR[5]&mulR[4]&mulR[3])|(mulR[5]&~mulR[4]&~mulR[3]);
assigntwo4=(~mulR[7]&mulR[6]&mulR[5])|(mulR[7]&~mulR[6]&~mulR[5]);
//·ûºÅÀ©Õ¹
wire[15:
0]temp;
assigntemp={{8{mulD[7]}},mulD[7:
0]};
//¼ÆËãÊä³ö
wire[15:
0]dat_w1,dat_w2,dat_w3,dat_w4;
//-2*B==(~(B<<1))+1;2B=(B<<1);
assigndat_w1=(two1)?
((sign1)?
{temp[14:
0],1'b0}:
(~{temp[14:
0],1'b0}+1'b1)):
((one1)?
((sign1)?
temp:
{~temp+1'b1}):
0);
assigndat_w2=(two2)?
((sign2)?
{temp[14:
0],1'b0}:
(~{temp[14:
0],1'b0}+1'b1)):
((one2)?
((sign2)?
temp:
{~temp+1'b1}):
0);
assigndat_w3=(two3)?
((sign3)?
{temp[14:
0],1'b0}:
(~{temp[14:
0],1'b0}+1'b1)):
((one3)?
((sign3)?
temp:
{~temp+1'b1}):
0);
assigndat_w4=(two4)?
((sign4)?
{temp[14:
0],1'b0}:
(~{temp[14:
0],1'b0}+1'b1)):
((one4)?
((sign4)?
temp:
{~temp+1'b1}):
0);
assignValOut=dat_w1+{dat_w2[13:
0],2'b00}+{dat_w3[11:
0],4'b0000}+{dat_w4[9:
0],6'b000000};
assignmulD=multiplicand;
assignmulR=multiplier;
endmodule
2.4时钟问题:
⑴利用与门、D触发器等器件,分别画出如下两段代码的框图。
⑵指出在FPGA中采用哪种处理方式
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- fpga 笔试
![提示](https://static.bdocx.com/images/bang_tan.gif)