数电自主设计实验报告Verilog秒表.docx
- 文档编号:29874049
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:17
- 大小:1.01MB
数电自主设计实验报告Verilog秒表.docx
《数电自主设计实验报告Verilog秒表.docx》由会员分享,可在线阅读,更多相关《数电自主设计实验报告Verilog秒表.docx(17页珍藏版)》请在冰豆网上搜索。
数电自主设计实验报告Verilog秒表
姓名班级学号
实验日期节次教师签字成绩
基于BASYS2开发板的
记忆秒表设计
1、实验目的
1、熟悉基于VerilogHDL语言输入方式的数字电路的设计方法。
2、掌握基于FPGA的设计流程。
3、熟悉BASYS2开发板的使用方法。
4、熟悉XilinxISE软件的使用方法。
5、培养自己独立自主设计并完成实验的能力。
2、总体设计方案或技术路线
本实验利用BASYS2开发板的已有资源来进行设计实验,并用XilinxISE软件来编写和综合Verilog代码。
总体设计方案是设计一个带有记忆功能的秒表。
具体而言,该秒表通过BASYS2开发板的50M的时钟进行分频计时,最大计时时间为99.99s,用4位数码管动态显示计时时间,除了有基本的运行、暂停及复位清空功能,还有存储当前时间和查看存储时间的功能。
3、实验电路图
BASYS2开发板原理图--数码管
板上数码管为4位共阳极数码管,每段为低电平点亮,位选接了三极管增大驱动电流,同时为非逻辑,所以位选信号为低电平有效。
BASYS2开发板原理图--按键
本实验用到了两个按键BTN0和BTN1,BTN0为复位按键,对应程序的clear信号,BTN1为存储按键,对应程序的btn[1]信号,按一次该按键数据存储一次,下一次按下时这一次存的数据将被替换掉。
BASYS2开发板原理图--开关
本实验用到了两个开关SW7和SW1,SW7为运行、暂停开关,对应程序的sw[0]信号,开关打到上方为运行,下方为暂停,SW1为显示切换开关,对应程序的sw[1]信号,在计时暂停的前提下,将开关打到上方显示出存储的时间数据。
4、仪器设备名称、型号和技术指标
硬件:
BASYS2开发板
软件:
XilinxISE(编程)、DigilentAdept(下载)
5、程序流程图
6、程序源代码
/////////////////////////////////////////////////////////程序文件
`timescale1ns/1ps
//////////////////////////////////////////////////////////////////////////////////
//Company:
//Engineer:
//
//CreateDate:
15:
45:
0111/26/2014
//DesignName:
//ModuleName:
miaobiao
//ProjectName:
//TargetDevices:
//Toolversions:
//Description:
//
//Dependencies:
//
//Revision:
//Revision0.01-FileCreated
//AdditionalComments:
//
///////////////////////////////////////////////////////////秒表的顶层模块
modulemiaobiao(
inputwireclk,///////////////////////////////开发板系统时钟50MHz
inputwire[1:
0]btn,////////////////////////两个按键:
[0]复位和[1]存时间
inputwire[1:
0]sw,/////////////////////////两个开关:
[0]运行/暂停和[1]显示存储时间
outputwire[7:
0]smg,/////////////////////数码管的8个段选信号
outputwire[3:
0]smg_an/////////////////数码管的4个位选信号
);
wireclear;
assignclear=btn[0];////////////////////////////////////将复位按键信号传给clear变量
wireclk_1k;
clkdiv#(50000)m0(clk,clear,clk_1k);//将50MHz进行5万分频输出1kHz时钟信号
wire[15:
0]number;
timerm1(sw[0]&clk_1k,clear,number);///////////计时器模块,输出当前时间数据
wire[15:
0]num_save;
savem2(clk,clear,btn[1],number,num_save);//////按键按下存储当前时间
wire[15:
0]num_display;
/////////////////////////////////////////////////////////////////////////////根据开关状态选择显示内容
choose_4numm3(sw,number,num_save,num_display);
displaym4(clk_1k,clear,num_display,smg,smg_an);///////将数字送给数码管显示
endmodule
///////////////////////////////////////////////////////////////////////////////4选1数据选择器模块
modulechoose_4num(
inputwire[1:
0]sw,
inputwire[15:
0]number,
inputwire[15:
0]num_save,
outputreg[15:
0]num_display
);
always@(*)
case(sw)
0:
num_display<=number;/////////////显示内容为当前时间
1:
num_display<=number;/////////////。
。
。
。
。
。
。
。
。
当前时间
2:
num_display<=num_save;/////////显示内容为存储时间
3:
num_display<=number;/////////////。
。
。
。
。
。
。
。
。
当前时间
default:
num_display<=number;
endcase
endmodule
//////////////////////////////////////////////////////////////////////////////////存储时间模块
modulesave(
inputwireclk_save,
inputwireclear,
inputwirebutton,
inputwire[15:
0]number,
outputreg[15:
0]num_save
);
always@(posedgeclk_save)
begin
if(1==clear)
num_save<=0;
elseif(1==button)
num_save<=number;
else
num_save<=num_save;
end
endmodule
//////////////////////////////////////////////////////////////////////////////////////计时器模块
moduletimer(
inputwireclk_timer,
inputwireclear,
outputreg[15:
0]number
);
reg[3:
0]reg_1ms;
always@(posedgeclk_timer,posedgeclear)
begin
if(1==clear)
begin
number<=0;
reg_1ms<=0;
end
else
begin
reg_1ms<=reg_1ms+1;
if(reg_1ms>=9)///////////////1ms的计数变量到10清零,同时10ms变量加一
begin
reg_1ms<=0;
number[3:
0]<=number[3:
0]+1;
if(number[3:
0]>=9)////10ms变量到10清零,100ms加一
begin
number[3:
0]<=0;
number[7:
4]<=number[7:
4]+1;
if(number[7:
4]>=9)////100ms变量到10清零,1s加一
begin
number[7:
4]<=0;
number[11:
8]<=number[11:
8]+1;
if(number[11:
8]>=9)/////1s到10清零,10s加一
begin
number[11:
8]<=0;
number[15:
12]<=number[15:
12]+1;
if(number[15:
12]>=9)////10s变量到10清零
number[15:
12]<=0;///综上,计时到99.99s后清零
end
end
end
end
end
end
endmodule
/////////////////////////////////////////////////////////////////////////////////////动态扫描显示数字模块
moduledisplay(
inputwireclk_dis,
inputwireclear,
inputwire[15:
0]number,
outputwire[7:
0]smg,
outputwire[3:
0]smg_an
);
reg[1:
0]counter;
reg[3:
0]reg_num;
wiredp;
always@(posedgeclk_dis,posedgeclear)
begin
if(1==clear)
begin
counter<=0;
end
else
counter<=counter+1;
end
always@(*)
begin
case(counter)
0:
reg_num<=number[3:
0];////////将10ms变量送到数码管第0位显示
1:
reg_num<=number[7:
4];////////将100ms变量送到数码管第1位显示
2:
reg_num<=number[11:
8];//////将1s变量送到数码管第2位显示
3:
reg_num<=number[15:
12];////将10s变量送到数码管第3位显示
default:
reg_num<=0;
endcase
end
assigndp=(2==counter);//////////////////第2位数码管的小数点点亮,其余小数点熄灭
num2smgm0(counter,reg_num,dp,smg_an,smg);
endmodule
//////////////////////////////////////////////////////////////////////////////////////时钟分频模块
moduleclkdiv
#(parameterdiv=50000)///////默认5万分频
(inputwireclk,
inputwireclear,
outputregnew_clk
);
reg[31:
0]counter;
always@(posedgeclk,posedgeclear)
begin
if(1==clear)
begin
counter<=0;
new_clk<=0;
end
elseif(counter>=div/2-1)
begin
counter<=0;
new_clk<=~new_clk;//二分频
end
else
counter<=counter+1;
end
endmodule
///////////////////////////////////////////////////////////////////////////数字转换成数码管段、位码模块
modulenum2smg(
//inputwireclk_smg,
inputwire[1:
0]which,
inputwire[3:
0]num,
inputwiredp,//dp=1时,点亮小数点
outputreg[3:
0]smg_an,
outputwire[7:
0]smg
);
always@(*)
case(which)/////////////////////////////////////////数码管位选子模块
3:
smg_an<=4'b0111;
2:
smg_an<=4'b1011;
1:
smg_an<=4'b1101;
0:
smg_an<=4'b1110;
default:
smg_an<=4'b1111;
endcase
reg[7:
0]r_smg;
always@(*)//////////////////////////////////////////////数码管段选子模块
begin
case(num)
0:
r_smg<=8'hc0;
1:
r_smg<=8'hf9;
2:
r_smg<=8'ha4;
3:
r_smg<=8'hb0;
4:
r_smg<=8'h99;
5:
r_smg<=8'h92;
6:
r_smg<=8'h82;
7:
r_smg<=8'hf8;
8:
r_smg<=8'h80;
9:
r_smg<=8'h90;
10:
r_smg<=8'h88;
11:
r_smg<=8'h83;
12:
r_smg<=8'hc6;
13:
r_smg<=8'ha1;
14:
r_smg<=8'h86;
15:
r_smg<=8'h8e;
default:
r_smg<=8'hff;
endcase
end
assignsmg=r_smg-128*dp;////////////////////////////////////判断是否显示小数点
endmodule
////////////////////////////////////////////////////////////////////////////程序结束END
//////////////////////////////////引脚约束文件
////////////////////////////////////////////////////时钟约束
NET"clk"TNM_NET=clk;
TIMESPECTS_CLK=PERIOD"clk"20nshigh50%;
NET"clk"LOC="B8";
//////////////////////////////////////////////////////////数码管
NET"smg<7>"LOC="N13";
NET"smg<6>"LOC="M12";
NET"smg<5>"LOC="L13";
NET"smg<4>"LOC="P12";
NET"smg<3>"LOC="N11";
NET"smg<2>"LOC="N14";
NET"smg<1>"LOC="H12";
NET"smg<0>"LOC="L14";
NET"smg_an<3>"LOC="K14";
NET"smg_an<2>"LOC="M13";
NET"smg_an<1>"LOC="J12";
NET"smg_an<0>"LOC="F12";
//////////////////////////////////////////////////////按键
//NET"btn<3>"LOC="A7";
//NET"btn<2>"LOC="M4";
NET"btn<1>"LOC="C11";
NET"btn<0>"LOC="G12";
////////////////////////////////////////////////////开关
NET"sw<1>"LOC="L3";
NET"sw<0>"LOC="N3";
7、实验结果
最后,成功地编写出程序,调试通过,完成所有功能,整个设计达到预期目标:
最大计时时间为99.99s,用4位数码管动态显示计时时间,除了有基本的运行、暂停及复位清空功能,还有存储当前时间和查看存储时间的功能。
8、实验中出现的问题及解决对策
问题一:
数码管按照板子上给的位选引脚编号进行引脚约束后,发现4个数码管显示的内容恰好反过来。
解决对策:
用万用表检查电路后,再通过每一位数码管单独静态显示的测试后,证明确实是板子上给的引脚编号有误,在引脚约束文件中对4位数码管的引脚约束进行了修改之后,最后成功地改变了显示顺序,达到了预期的效果。
问题二:
每次综合的时候都出现了很多很多的错误和警告。
解决对策:
首先,通过软件给出的提示进行修改,解决了一部分错误和警告;然后,将错误和警告代码复制粘贴到网上进行搜索,寻找解决方案,又解决了一部分错误和警告;最后,给老师和学长发邮件请教,或者当面请教寻求帮助,解决了所有错误和又一部分警告,剩下几个警告直接无视,下载到开发板后证明对秒表的功能没有任何影响,说明这些警告可以忽视。
9、本次实验的收获和体会、对电路实验室的意见或建议
收获和体会:
本次实验,我从一开始的完全不懂FPGA到最后学会FPGA并且成功完成整个实验内容,我最大的收获就是一种自信和成就感,这增加了我在以后的学习生活中面对困难时的勇气和决心。
在老师教授FPGA之前,我自己尝试去提前自学FPGA,边看文档边学习,通过对例程的编写和思考完成了基础知识的构建,然后自己编程锻炼和提高编程水平。
在FPGA的编程控制过程中,我建立了模块化编程的思想,明白了FPGA触发式的运行方式,初步学会了FPGA编程,并且对FPGA产生了浓厚的兴趣。
但是,从另一方面我也明白了自己掌握的知识只是冰山一角,要想能力更强,还需要付出更多努力。
意见和建议:
1、希望实验室可以根据课程进度安排实验内容。
2、希望实验室能举办更多的FPGA的培训。
3、希望仿真实验室能在所有电脑上都安装XilinxISE软件。
4、希望实验室能定期检查领取了BASYS2开发板的同学的学习进度,或者安排定期必须完成的小任务,督促大家认真学习BASYS2开发板。
10、参考文献
[1]廉玉欣.电子技术基础实验教程.北京:
机械工业出版社,2013.2.
[2]孟涛.电工电子EDA实践教程.北京:
机械工业出版社,2010.2.
[3]王伟.VerilogHDL程序设计与应用.北京:
人民邮电出版社,2005.3.
[4]云创工作室.VerilogHDL程序设计与实践.北京:
人民邮电出版社,2009.2.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 自主 设计 实验 报告 Verilog 秒表