FPGA实验报告.docx
《FPGA实验报告.docx》由会员分享,可在线阅读,更多相关《FPGA实验报告.docx(28页珍藏版)》请在冰豆网上搜索。
![FPGA实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/24/5992bc2a-ef0c-4ace-8694-ae434678833b/5992bc2a-ef0c-4ace-8694-ae434678833b1.gif)
FPGA实验报告
本科生实习报告
实习名称:
FPGA综合实验
姓名:
学院:
电气与控制工程学院
专业班级:
学号:
指导教师:
二O一七年三月
基本信息
实习学生信息
姓名
性别
女
学号
出生年月
1996年2月
学院
电器与控制工程学院
专业
微电子科学与工程
班级
1302班
指导教师信息
姓名
性别
职称
女
工程师
男
副教授
实习单位信息
实习单位名称
单位地址
实习起至日期
自2017年3月6日
至2017年3月24日
自年月日
至年月日
自年月日
至年月日
自年月日
至年月日
自年月日
至年月日
实习记录
周次
实习内容记录
病事假
记录
第
一
周
周一
了解FPGA综合实验内容和要求;
选择FPGA综合实验的题目;
查阅相关资料。
周二
整理和学习相关资料;
确定整体设计思路。
周三
根据系统功能要求进一步完善设计方案。
周四
进行硬件电路原理分析与设计。
周五
对所涉及的电路进行分析,确定相关参数
第
二
周
周一
根据系统功能要求,采用硬件描述语言进行设计
周二
各功能模块设计
周三
各功能模块设计
周四
各功能模块设计
周五
各功能模块仿真验证
实习记录
周次
实习内容记录
病事假
记录
第
三
周
周一
系统整体仿真与分析
周二
下载程序到FPGA开发板,软件、硬件联合调试验证
周三
编程下载与调试验证
周四
调试验证成功后,给老师验收实验结果,撰写实验报告
周五
提交实验报告
第
四
周
周一
周二
周三
周四
周五
实验报告
基于FPGA的计算器设计与实验
1、实验目的
毕业实习是本科教学培养方案和教学计划的重要环节,是培养学生综合运用所学专业知识,分析总结和解决实际问题的最后一次实践环节,也是大学四年所学知识的一次全面综合训练,同时也可以增强学生适应社会的能力和就业竞争力。
通过毕业实习,可以开阔学生视野、增强学生劳动观念;了解所学专业在工业生产要用到的设备、工作范围、工作性质;为毕业论文撰写积累经验。
2、实验内容
掌握4*4阵列键盘扫描原理,及存储器ROM、RAM的设计和应用,完成可以实现加减乘除功能的计算器的设计。
3、实验要求
用4*4阵列键盘输入0~99整数操作;
计算结果用LED数码管显示;
采用FPGA作为运算控制器实现加减乘除等等基础计算功能。
4、设计思路
先把计算器分为五个模块:
LED数码管显示模块,4*4键盘扫描分析电路,算术逻辑运算单元,数制转换模块,运算操作过程的状态机模块;然后分模块编写程序;最后用顶层文件将它们联系起来。
5、设计原理
5.1LED数码管显示模块设计原理
单个数码管共有8个显示段,每个显示段有一个独立的发光二极管组成,通过八位数据线控制LED的亮和灭,由此显示出设计者想要显示的字符和小数点。
本实验采用共阴数码管,因此,若显示某段LED的另外一端为低电平,则该断LED灯熄灭,反之则点亮。
5.24*4键盘扫描分析电路设计原理
通过行列扫描确定4*4键盘上数字及运算符的准确位置,为防止按键按下瞬间链接不稳定,在扫描模块中添加了去除按键抖动部分。
4×4矩阵键盘原理图(图1)如下:
图14×4矩阵键盘原理图
5.3算术逻辑运算单元设计原理
操作数a,b以及操作符opcode从键盘输入并转换为二进制数存入寄存器
A、B,算数逻辑模块只做相应算数运算,对opcode=10、11、12、13时分别为加、减、乘、除。
5.4数制转换
(1)BCD码转制二进制码模块:
计算模块只能对二进制进行运算,所
以需要将BCD码转成二进制数,才能送入计算模块进行运算。
其转换方法为:
assigna[23:
0]=BCDa[23:
20]*100000+BCDa[19:
16]*10000+
BCDa[15:
12]*1000+BCDa[11:
8]*100+BCDa[7:
4]*10+BCDa[3:
0];
(2)二进制码转制BCD码模块:
计算结果需要用数码管显示,必须将
二进制数转成BCD码才能正常显示。
其转换方法为:
assignbcd[23:
20]=bin/100000;
assignbcd[19:
16]=(bin/10000)%10;
assignbcd[15:
12]=(bin/1000)%10;
assignbcd[11:
8]=(bin/100)%10;
assignbcd[7:
4]=(bin/10)%10;
assignbcd[3:
0]=bin%10;
六、实验结果
6.1加法运算(如图2)
12+12=?
图2
6.2减法运算(如图3)
12-3=?
图3
6.3乘法运算(如图4)
12*3=?
图4
6.4除法运算(如图5)
12/3=?
图5
七、遇到问题与解决方法
7.1问题:
刚开始编写的程序中,错误比较多,也比较难找问题
解决方法:
经老师提示,将程序分模块编写,然后分模块仿真,查找错误比较容易。
7.2问题:
下载到实验箱后,按键后,数码管显示出现乱码
解决方法:
检查程序后,发现程序是适用于共阳数码管的,将之改成适应于共阴的。
8、心得体会
三周的实训已经过去了,我们在老师提供的实践平台上通过自己的实践学到了很多课本上学不到的宝贵东西,熟悉了对QuartusⅡ软件的一般项目的操作和学到了处理简单问题的基本方法,加深了对硬件描述语言的理解,尤其是本课题中乘法器的设计让我更清楚进程、变量、信号的使用及它们之间的区别。
意识到了课程设计的重要性以及团队合作对于设计的重要性,更重要的是掌握了硬件描述语言的基本设计思路和方法,我想这些会对我今后的学习起到很大的助推作用。
我还了解到了要加强培养动手能力,要明白理论与实践结合的重要性,只有理论知识也是不够的,只有把理论知识和实践相结合,才能真正提高我们的实际动手能力与独立思考的能力。
感谢学院给我们提供这次实训的机会,感谢老师对我们的指导,教会了我们如何运用所学的知识去解决实际的问题,此外,还得出一个结论:
知识必须通过应用才能实现其价值!
有些东西以为学会了,但真正到用的时候才发现是两回事,所以我认为只有到真正会用的时候才是真的学会了。
今后的理论知识学习过程中要一步一个脚印的扎实学习,灵活的掌握和运用专业理论知识这样才能在以后出去工作的过程中有所成果。
附录
程序清单:
调用子程序模块:
modulecal(clk,rst_n,seg,sel,keyin,keyscan);
inputclk,rst_n;
input[3:
0]keyin;
output[3:
0]keyscan;
output[2:
0]sel;
output[7:
0]seg;
wireclk_slow;
wire[4:
0]real_number;
wire[23:
0]BCDa,BCDb,a,b,bin_data,result;
wire[3:
0]opcode;
displayu1(
.clk(clk),
.adata(BCDa),
.bdata(BCDb),
.rst_n(rst_n),
.sel(sel),
.seg(seg),
.clk_slow(clk_slow)
);
keyscanu2(
.clk(clk_slow),
.rst_n(rst_n),
.keyscan(keyscan),
.keyin(keyin),
.real_number(real_number)
);
keybcdu3(
.clk(clk_slow),
.real_number(real_number),
.opcode(opcode),
.rst_n(rst_n),
.BCDa(BCDa),
.BCDb(BCDb),
.result(result)
);
bcdbinu4(
.BCDa(BCDa),
.BCDb(BCDb),
.a(a),
.b(b)
);
binbcdu5(
.bin(bin_data),
.bcd(result)
);
aluu6(
.a(a),
.b(b),
.clk(clk_slow),
.rst_n(rst_n),
.opcode(opcode),
.bin_data(bin_data)
);
Endmodule
数码管显示模块:
moduledisplay(clk,rst_n,adata,bdata,sel,seg,clk_slow);
inputclk;
inputrst_n;
input[23:
0]adata,bdata;//状态机输出?
/
outputreg[2:
0]sel;//weixuan//
outputreg[7:
0]seg;//duanxuan//
wire[23:
0]data;
reg[3:
0]segdata;
reg[15:
0]cnt;//jishuqi/
outputregclk_slow;
assigndata=(bdata==0)?
adata:
bdata;//b=0--1
always@(posedgeclk)
begin
if(!
rst_n)
begin
cnt<=0;
clk_slow<=1;
end
else
begin
cnt<=cnt+1;
clk_slow<=cnt[12];
end
end
always@(posedgeclk_slowornegedgerst_n)//saomiao
begin
if(!
rst_n)
begin
sel<=0;
end
else
begin
sel<=sel+1;
if(sel>=5)
sel<=0;
end
end
always@(*)
begin
if(!
rst_n)
begin
segdata<=0;
end
else
begin
case(sel)
5:
segdata<=data[3:
0];//ge
4:
segdata<=data[7:
4];//shi
3:
segdata<=data[11:
8];
2:
segdata<=data[15:
12];
1:
segdata<=data[19:
16];
0:
segdata<=data[23:
20];
default:
segdata<=0;
endcase
end
end
always@(*)
begin
if(!
rst_n)
begin
seg<=8'hff;
end
else
begin
case(segdata)
0:
seg<=8'b00111111;//R--AL--.dp
1:
seg<=8'b00000110;
2:
seg<=8'b01011011;
3:
seg<=8'b01001111;
4:
seg<=8'b01100110;
5:
seg<=8'b01101101;
6:
seg<=8'b01111101;
7:
seg<=8'b00000111;
8:
seg<=8'b01111111;
9:
seg<=8'b01101111;
default:
seg<=8'b00000000;
endcase
end
end
Endmodule
键盘扫描模块:
`defineOK1'b1
`defineNO1'b0
`defineNoKeyIsPressed17
modulekeyscan(clk,rst_n,keyscan,keyin,real_number);
inputclk,rst_n;
input[3:
0]keyin;//hangsaomiao
output[3:
0]keyscan;//lieshuchu
output[4:
0]real_number;
reg[3:
0]state;
reg[3:
0]four_state;
reg[3:
0]scancode,scan_state;
reg[4:
0]numberout,number_reg,number_reg1,number_reg2,real_number;
regAnyKeyPressed;
assignkeyscan=scancode;
always@(posedgeclk)
if(!
rst_n)
begin
scancode<=4'b0000;
scan_state<=4'b0000;
end
else
if(AnyKeyPressed)//pressbottonscan--start
case(scan_state)
4'b0000:
beginscancode<=4'b1110;scan_state<=4'b0001;end
4'b0001:
beginscancode<={scancode[0],scancode[3:
1]};end
endcase
else
begin
scancode<=4'b0000;
scan_state<=4'b0000;
end
always@(posedgeclk)
if(!
(&keyin))
begin
AnyKeyPressed<=`OK;
four_state<=4'b0000;
end
else
if(AnyKeyPressed)
case(four_state)
4'b0000:
beginAnyKeyPressed<=`OK;four_state<=4'b0001;end
4'b0001:
beginAnyKeyPressed<=`OK;four_state<=4'b0010;end
4'b0010:
beginAnyKeyPressed<=`OK;four_state<=4'b0100;end
4'b0100:
beginAnyKeyPressed<=`OK;four_state<=4'b1000;end
4'b1000:
beginAnyKeyPressed<=`NO;end
default:
AnyKeyPressed<=`NO;
endcase
else
four_state<=4'b0000;
always@(posedgeclk)//quedinganjian
casex({scancode,keyin})
8'b0111_1110:
numberout<=5'd10;//+
8'b1011_1110:
numberout<=5'd11;//-
8'b1101_1110:
numberout<=5'd12;//*
8'b1110_1110:
numberout<=5'd13;//\
8'b0111_1101:
numberout<=5'd3;
8'b1011_1101:
numberout<=5'd6;
8'b1101_1101:
numberout<=5'd9;
8'b1110_1101:
numberout<=5'd14;//?
8'b0111_1011:
numberout<=5'd2;
8'b1011_1011:
numberout<=5'd5;
8'b1101_1011:
numberout<=5'd8;
8'b1110_1011:
numberout<=5'd0;
8'b0111_0111:
numberout<=5'd1;
8'b1011_0111:
numberout<=5'd4;
8'b1101_0111:
numberout<=5'd7;
8'b1110_0111:
numberout<=5'd15;//=
default:
numberout<=`NoKeyIsPressed;
endcase
always@(posedgeclk)
begin
if(!
rst_n)
begin
number_reg<=0;
end
else
if(numberout<=5'd15&&numberout>=5'd0)
begin
number_reg<=numberout;//anjianzhicunrujicunqi
end
else
begin
if(AnyKeyPressed==`NO)
number_reg<=`NoKeyIsPressed;
end
end
always@(posedgeclk)//xiaochuanjiandoudong
if(!
rst_n)
state<=4'b0000;
else
case(state)
4'd0:
begin
number_reg1<=number_reg;
state<=4'd1;
end
4'd1:
begin
if(number_reg==number_reg1)
state<=4'd2;
else
state<=4'd0;
end
4'd2:
begin
if(number_reg==number_reg1)
state<=4'd3;
else
state<=4'd0;
end
4'd3:
begin
if(number_reg==number_reg1)
state<=4'd4;
else
state<=4'd0;
end
4'd4:
begin
if(number_reg==number_reg1)
state<=4'd5;
else
state<=4'd0;
end
4'd5:
begin
if(number_reg==number_reg1)
state<=4'd6;
else
state<=4'd0;
end
4'd6:
begin
if(number_reg==number_reg1)
state<=4'd7;
else
state<=4'd0;
end
4'd7:
begin
if(number_reg==number_reg1)
state<=4'd8;
else
state<=4'd0;
end
4'd8:
begin
if(number_reg==number_reg1)
state<=4'd9;
else
state<=4'd0;
end
4'd9:
begin
if(number_reg==number_reg1)
state<=4'd10;
else
state<=4'd0;
end
4'd10:
begin
if(number_reg==number_reg1)
state<=4'd11;
else
state<=4'd0;
end
4'd11:
begin
if(number_reg==number_reg1)
state<=4'd12;
else
state<=4'd0;
end
4'd12:
begin
if(number_reg==number_reg1)
state<=4'd13;
else
state<=4'd0;
end
4'd13:
begin
if(number_reg==number_reg1)
state<=4'd14;
else
state<=4'd0;
end
4'd14:
begin
if(number_reg==number_reg1)
state<=4'd15;
else
state<=4'd0;
end
4'd15:
begin
if(number_reg==number_reg1)
begin
state<=4'd0;
real_number<=number_reg;
end
else
state<=4'b0000;
end
default:
state<=4'b0000;
endcase
endmodule
状态机模块:
modulekeybcd(clk,
rst_n,
real_number,
opcode,//yunsuanfuhao
BCDa,
BCDb,
result);
input[4: