哈工大数电自主设计实验免试报告模板.docx
《哈工大数电自主设计实验免试报告模板.docx》由会员分享,可在线阅读,更多相关《哈工大数电自主设计实验免试报告模板.docx(27页珍藏版)》请在冰豆网上搜索。
哈工大数电自主设计实验免试报告模板
姓名班级1204104班学号
实验日期节次教师签字成绩
基于Basys2开发板的推理速记智力游戏的设计
1.实验目的
(1)了解有关FPGA的基本知识及其应用方法;
(2)掌握用verilogHDL语言硬件描述语言编写程序;
(3)了解Basys2开发板的结构及其可拓展的外设;
(4)掌握ISE综合工具、仿真工具的使用及整个设计的流程;
(5)通过对可编程逻辑器件的学习,为未来的学习打下基础
2.总体设计方案或技术路线
本实验是基于Basys2开发板的一个综合了快速推理能力、快速记忆能力的智力游戏的模型设计。
基本游戏规则如下:
1.游戏系统与游戏者交互的内容有五项,提示用led灯四个、答案显示用led灯四个、计分数码管、输入用按键4个和开关输入;
2.每次游戏开始,根据开关选择情况,确定一组提示灯与按钮的对应顺序,每隔3s,提示灯随机亮一盏,按下一个按钮,若为该灯所对应的按钮,则该灯对应的答案灯亮,否则不亮;
3.每亮一次提示灯的时间内,只能按下一次按键;
4.每亮一次灯,操作步数加一,在计分数码管上显示出来;
5.若当前的提示灯对应的答案灯已经点亮,那么用户可以选择按下按钮或者不按,若按错,作为惩罚操作步数额外加一,按对则减一,不按不影响,适当放弃也是一种策略;
6.答案灯全点亮时游戏胜利,同时点亮所有灯,游戏停止,记录操作步数;
7.操作步数达到40以上时判定游戏失败,所有灯灭,游戏停止。
根据以上规则,我一共设计了五大模块,分别为时钟分频模块(clk_mod)、游戏初始模块(start_mod)、提示灯模块(led_mod)、数码管显示模块(segment_mod)、判断按键模块(judge_mod)。
下面简单介绍各模块功能,
分频模块:
由于Basys2本身时钟频率较高,将时钟分频用以驱动相应模块。
游戏初始模块:
确定本次游戏的答案对应顺序。
提示灯模块:
随机点亮提示灯。
数码管显示模块:
显示计分。
判断按键模块:
判断答案同时计分。
以上简略介绍了本实验的各个模块基本功能,具体的实现方式及详细介绍,在下面的电路分析部分给出。
3.实验电路图
我将先按照从模块分别介绍再到顶层模块介绍依次介绍本实验电路。
(1)分频模块
该模块有两个输入和两个输出,输入clk为系统自带时钟,频率为50Hz,输入reset为复位功能开关,输出clk_delay为周期为3秒的时钟,用以驱动提示灯模块每三秒亮一盏灯,输出clk_delay_2ms为周期为2ms的时钟,用以驱动数码管显示模块,因为50MHz高频率下数码管显示不稳定。
(2)游戏初始模块
该模块有三个输入和一个输出,输入端clk和reset分别为时钟和复位功能,输入端switch为五位开关输入,用来选择本次游戏所需的游戏对应答案顺序。
输出端judge_array输出一组16位二进制数用以表示对应顺序,输出到判断按键模块供其判断答案正误。
(3)提示灯模块
该模块有四个输入和一个输出,输入端reset为复位功能开关,输入端clk_delay为clk_mod提供的3s周期时钟驱动,输入端led2和step_num_out都由下面将要介绍的判断按键模块输出提供,用以判断当前游戏胜利或失败状态,led2判断胜利,step_num_out判断失败,然后根据当前状态处于游戏中或游戏胜利或游戏失败由输出端led1输出不同提示灯状态。
游戏中亮相应灯,游戏胜利灯全亮,游戏失败灯全灭。
(4)判断按键模块
该模块有六个输入和两个输出,输入端clk为时钟输入,输入端reset为复位功能开关,输入端clk_delay为clk_mod提供的3s周期时钟驱动,用以判断是否新点亮一盏灯,从而使按键处于按下有效状态,从而实现每次亮灯只能按下一次按键有效,输入led1、judge_array、key为提示灯状态、对应顺序、按键状态三者,从而判断答案正误。
输出端led2为答案显示灯,输出端step_num_out为操作步数输出,输出到led_mod用于判断,输出到数码管显示模块用于显示操作步数。
(5)数码管显示模块
该模块有四个输入端和两个输出端,输入端clk为时钟输入,输入端reset为复位功能开关,输入端clk_delay_2ms为clk_mod提供的2ms周期时钟驱动,输入step_num_in为操作步数输入,输出端seg_num_out为数码管段选,输出端seg_pos_out为数码管位选。
(6)顶层模块连接图
该图显示了各个模块的连接关系,与上面的各个介绍一致。
整体输入有clk时钟,switch开关,reset复位开关,用户按键key,输出为数码管、led灯。
4.仪器设备名称、型号和技术指标
Basys2开发板1块
PC1台
ISE13.4开发平台及仿真工具
5.理论分析或仿真分析结果
下面,我将分模块进行假定用户输入下的仿真。
(1)时钟分频模块仿真
由上图可以看出每2ms,clk_delay_2ms的波形会出现一个峰值,仿真结果正确。
由上图可以看出每3s,clk_delay的波形会出现一个峰值,仿真结果正确。
(2)游戏初始模块仿真
假定switch输入为五位二进制数01010,可以看到输出judge_array输出一组十六位二进制数010*********,仿真结果正确。
(4)整体仿真
提示灯模块、判断按键模块属于整体游戏过程,数码管模块属于显示输出,这三个模块需要其他模块驱动,故与整体一起仿真。
设定假设用户输入如上图,假设用户按键为按下第三个键。
通过以上验证可以看出,switch为00000时,理论对应关系应为当led1为0010时,按键0010为正确答案,此时led2变为0010,仿真结果正确;
6.详细实验步骤及实验测量数据记录
实验步骤如下:
1.了解verilog语言语法及设计方法
2.设计游戏规则
3.根据游戏规则及verilog语法设计相应模块
4.了解basys2开发板结构,决定输入输出控制
5.编写基本游戏过程代码
6.通过综合工具调试代码
7.下载至basys2开发板进行调试
8.完善更多细节功能,通过实践发现bug,分析bug原因加以改进
9.最终调试及检测
7.实验结论
实现了设计的全部功能,以下是成果展示:
游戏失败照片
游戏胜利照片
游戏过程中照片
8.实验中出现的问题及解决对策
我将本次实验的问题分为两类,一类是程序逻辑设计上的问题,一类是开发板及verilog语言使用上的问题下面逐一介绍:
1.本次实验过程中,由于第一次上手,遇到了很多的问题,开发板使用方面,在程序设计时遇到了很多的警告与错误,下面是我总结的我的常见错误:
(1)不同always语句中对同一变量赋值操作;
(2)顶层模块调用时,各模块中间的输入输出需要定义wire,且注意命名不能出错;
(3)注意数制,输入数时均按照二进制位数输入;
(4)调用case,if语句时记得end终止;
(5)调用case,if语句时,用不上的条件情况最好也加以说明,哪怕default后加空语句,可减少不必要的警告。
2.游戏逻辑设计上的问题
(1)如何使每局游戏对应关系唯一?
使用了一个标志量,只有reset时使标志量重置,一旦产生对应关系,则利用标志量使模块不再产生新的对应关系。
(2)如何使一次亮灯后只有一次按键有效?
同样使用标志量,只有新的灯亮后,标志量重置,使按键有效。
(3)如何判断游戏胜利、失败和游戏状态?
令led_mod和和judge_mod互相输入对方模块的输出,达到模块间信息交互,从而判断各种状态。
9.本次实验的收获和体会、对电路实验室的意见或建议
通过本次实验,熟悉了通过verilog语言在ISE平台编写调试程序并下载到fpga实验的整体流程,深入了解了verilog模块化编程的思想与可编程逻辑器件的编程思想。
通过这次实验,不仅是对fpga,对于数电这门也有了新的认识,同时初步了解fpga的设计方法,对于以后也有很大的帮助。
建议实验室开设更多培训,可以提供一些常用的的外设,让我们可以设计并完成更多样实验。
10.参考文献
[1] 沈涛,李传志,张小平,李斌.Xilinx FPGA/CPLD设计初级教程[M].西安电子科技大学出版社,2009.
[2]杜勇.FPGA/VHDL设计入门与进阶[M].机械工业出版社,2011.
[3]周兴华.手把手教你学CPLD/FPGA与单片机联合设计[M].北京航空航天大学出版社,2010.11.
附录I本次实验代码
moduletest77(
inputclk,
inputreset,
input[4:
0]switch,
output[3:
0]seg_pos_out,
output[6:
0]seg_num_out,
input[3:
0]key,
output[7:
4]led1,
output[3:
0]led2
);
wireclk_delay_w;
wire[5:
0]step_num_out_w;
wire[16:
1]judge_array_w;
wireclk_delay_2ms_w;
clk_modclk_mod(
.clk(clk),
.reset(reset),
.clk_delay(clk_delay_w),
.clk_delay_2ms(clk_delay_2ms_w)
);
start_modstart_mod(
.clk(clk),
.reset(reset),
.switch(switch),
.judge_array(judge_array_w)
);
segment_modsegment_mod(
.clk(clk),
.reset(reset),
.step_num_in(step_num_out_w),
.clk_delay_2ms(clk_delay_2ms_w),
.seg_pos_out(seg_pos_out),
.seg_num_out(seg_num_out)
);
led_modled_mod(
.clk_delay(clk_delay_w),
.reset(reset),
.step_num_out(step_num_out_w),
.led2(led2),
.led1(led1)
);
judge_modjudge_mod(
.clk(clk),
.reset(reset),
.led1(led1),
.key(key),
.clk_delay(clk_delay_w),
.judge_array(judge_array_w),
.led2(led2),
.step_num_out(step_num_out_w)
);
endmodule
//------------时钟分频模块--------------------------------------------------
moduleclk_mod(
inputclk,
inputreset,
outputclk_delay,
outputclk_delay_2ms
);
reg[32:
1]time_delay;
reg[32:
1]time_cal=0;
reg[32:
1]time_delay1;
reg[32:
1]time_cal1=0;
regclk_delay_out=0;
regclk_delay_2ms_out=0;
always@(posedgeclk)
begin
if(reset)begin
//
end
else
begin
time_delay=150000000;
time_delay1=100000;
time_cal=time_cal+1;
time_cal1=time_cal1+1;
if(clk_delay_out==1)begin
clk_delay_out=0;
end
if(time_cal==time_delay)begin
clk_delay_out=1;
time_cal=0;
end
if(clk_delay_2ms_out==1)begin
clk_delay_2ms_out=0;
end
if(time_cal1==time_delay1)begin
clk_delay_2ms_out=1;
time_cal1=0;
end
end
end
assignclk_delay=clk_delay_out;
assignclk_delay_2ms=clk_delay_2ms_out;
endmodule
//------------游戏开始产生对应关系--------------------------------------
modulestart_mod(
inputclk,
inputreset,
input[4:
0]switch,
output[16:
1]judge_array
);
reg[4:
0]rand_status;
reg[16:
1]judge_array_out;
always@(posedgeclk)
begin
if(reset)begin
//
end
else
begin
rand_status=switch[4:
0];
case(rand_status)
0:
beginjudge_array_out<=16'h8421;end
1:
beginjudge_array_out<=16'h8412;end
2:
beginjudge_array_out<=16'h8241;end
3:
beginjudge_array_out<=16'h8214;end
4:
beginjudge_array_out<=16'h8142;end
5:
beginjudge_array_out<=16'h8124;end
6:
beginjudge_array_out<=16'h4812;end
7:
beginjudge_array_out<=16'h4821;end
8:
beginjudge_array_out<=16'h4281;end
9:
beginjudge_array_out<=16'h4218;end
10:
beginjudge_array_out<=16'h4182;end
11:
beginjudge_array_out<=16'h4128;end
12:
beginjudge_array_out<=16'h2841;end
13:
beginjudge_array_out<=16'h2814;end
14:
beginjudge_array_out<=16'h2481;end
15:
beginjudge_array_out<=16'h2418;end
16:
beginjudge_array_out<=16'h2184;end
17:
beginjudge_array_out<=16'h2148;end
18:
beginjudge_array_out<=16'h1842;end
19:
beginjudge_array_out<=16'h1824;end
20:
beginjudge_array_out<=16'h1482;end
21:
beginjudge_array_out<=16'h1428;end
22:
beginjudge_array_out<=16'h1284;end
default:
beginjudge_array_out<=16'h1248;end
endcase
end
end
assignjudge_array=judge_array_out;
endmodule
//-----------------随机亮提示灯-----------------------------------------
moduleled_mod(
inputclk_delay,
inputreset,
input[3:
0]led2,
input[6:
0]step_num_out,
output[7:
4]led1
);
reg[1:
0]rand_led;
reg[3:
0]led_temp;
reg[3:
0]led_in;
reg[6:
0]step_num=0;
reg[31:
0]rand_num=32'b1101_1010_0110_1011_0010_1001_1011_0100;
always@(posedgeclk_delay)
begin
rand_num<=rand_num>>1;
rand_num[31]<=rand_num[0];
end
always@(posedgeclk_delayorposedgereset)
begin
if(reset)begin
led_temp<=4'b0000;
end
elsebegin
led_in=led2;
step_num=step_num_out;
if(led_in==4'b1111)begin
led_temp<=4'b1111;
end
elseif(step_num>39)begin
led_temp<=4'b0000;
end
elsebegin
rand_led=rand_num[7:
6];
case(rand_led)
0:
beginled_temp<=4'b0001;end
1:
beginled_temp<=4'b0010;end
2:
beginled_temp<=4'b0100;end
3:
beginled_temp<=4'b1000;end
endcase
end
end
end
assignled1[7:
4]=led_temp;
endmodule
//-----------------判断按键正误--------------------------------------------
modulejudge_mod(
inputclk,
inputreset,
input[7:
4]led1,
input[3:
0]key,
inputclk_delay,
input[16:
1]judge_array,
output[3:
0]led2,
output[6:
0]step_num_out
);
regflag=0;
reg[3:
0]led_answer=4'b0000;
reg[3:
0]led_temp_out;
reg[6:
0]step_num=7'd0;
always@(posedgeclk)
begin
if(reset)begin
led_answer<=4'b0000;
step_num=7'd0;
end
else
begin
if(step_num>6'd40)begin
led_answer<=4'b0000;
end
else
begin
if(clk_delay==1)begin
flag<=1;
if(led_answer<4'b1111)begin
step_num=step_num+1;
end
end
if(flag==1)begin
if(key>4'b0000)begin
led_temp_out=led1;
case(led_temp_out)
4'b0001:
begin
if(judge_array[4:
1]==key)begin
if({led_temp_out&led_answer}>0&&step_num>0)begin
step_num=step_num-1;
end
led_answer<=led_answer|led_temp_out;
end
else
begin
if({led_temp_out&led_answer}>0&&step_num>0)begin
step_num=step_num+1;
end
end
end
4'b0010:
begin
if(judge_array[8:
5]==key)begin
if({led_temp_out&led_answer}>0&&step_num>0)begin
step_num=step_num-1;
end
led_answer<=led_answer|led_temp_out;
end
else
begin
if({led_temp_out&led_answer}>0&&step_num>0)begin
step_num=step_num+1;
end
end
end
4'b0100:
begin
if(judge_array[12:
9]==key)begin
if({led_temp_out&led_answer}>0&&step_num>0)begin
step_num=step_num-1;
end
led_answer<=led_answer|led_temp_out;
end
else
begin
if({led_temp_out&led_answer}>0&&step_num>0)begin
step_num=step_num+1;
end
end
end
4'b1000:
begin
if(judge_array[16:
13]==key)begin
if({led_temp_out