资源描述
课程考查试题纸
课程名称:
EDA技术
考查内容:
综合设计报告 (随堂作业、论文、报告或其他)
学 院:
计算机与信息工程学院
任课教师:
******
专业年级:
********************
教师评语
总分
阅卷教师
……………………………………………………………………………………………………
综合设计题目:结合实验室EDA实验箱,完成一个可以计时的数字时钟,其显示时间范围是00:00 :00~23:59:59,且该时钟具有暂停计时和清零功能。
要求设计报告中有原理分析,实验步骤,程序代码,遇到的问题及解决方法,课程总结。
多功能数字钟
一.实验目的:
1. 回顾 Quartus II的使用步骤,强化对软件的熟练使用度。
2. 学习综合实验的设计思路及步骤。
3. 学习顶层模块的设计以及底层模块调用原理(即编程例化语句的使用)。
4. 进一步学习 Verilog HDL 语言的基本语法。
5. 熟练掌握时钟显示的原理及对应代码的编写。
6. 设计有特色的多功能可调的数字时钟。
7. 学会查阅相关资料,解决实验调试过程中遇到的问题。
二.实验环境 :
硬件环境:ALTERA公司开发板 Cyclone EP1C12Q240C8
软件环境:Quartus II开发软件
三.实验原理:
该时钟项目共分为六大模块,大顶层模块(LAB_TOP)、分频模块(ClkDivider)、分秒计数模块(Cnt_74161_fm)、时位计数模块(Cnt_74161_ss)、显示模块(scan_led)、消抖模块(debounce)。其中,分秒计数模块通过调整74161计数模块实现,从而达到分秒的六十进制;分频模块由系统时钟clock调整得到多种频率的信号输入;时位计数模块也通过调整74161计数模块实现;显示模块与动态显示数码管实验类似,段选和片选以及时钟的输入由顶层模块调用和产生以实现每位时钟数字的显示;消抖模块与按键实验类似,通过对信号的三次取或运算判断按键是否是正常输入信号以实现外加按键的正常控制,从而防止抖动产生的非正常信号输入;大顶层模块用来调用和整合各个模块以实现对每个模块的复用、调整和连接从而完成时钟的所有功能。该数字钟还添加了Load模式以实现外加按键对数字显示的调整,实现了有特色的多功能可调的数字时钟。
四.实验步骤:
1. 打开 Quartus II软件并建立工程设置好相应参数,并命名为clock.qpf。
2. 建立相关的文本编辑文件(File -> New -> Verilog HDL File)
具体过程如下:
分频模块(ClkDivider)
第5 页 共8页
module ClkDivider (input Clk_50,input Rst_n,
output reg Clk_div);
parameter CntThreshold = 25000;
reg [31:0] cnt;
always @ (posedge Clk_50 or negedge Rst_n)
begin
if (~Rst_n)
cnt <= 32'b0;
else if (cnt == CntThreshold - 1)
cnt <= 32'b0;
else
cnt <= cnt + 32'd1;
end
always @ (posedge Clk_50 or negedge Rst_n)
begin
if (~Rst_n)
Clk_div <= 1'b0;
else if (cnt == CntThreshold - 1)
Clk_div <= ~Clk_div;
else
Clk_div <= Clk_div;
end
endmodule
再将该Verilog HDL文件设置为顶层实体,进行编译,有错误则改正。
分秒计数模块(Cnt_74161_fm)
module Cnt_74161_fm(Q,Load_1,key_1,CLK,p, Clr,Stop);
input Load_1,key_1,Stop, CLK, Clr;
output reg [3:0] Q;
output reg [3:0] p;
parameter moshi = 9;
assign Tiaojie=(~Load_1)?(~key_1):CLK;
always @(negedge Clr or posedge Tiaojie)
if (~Clr)
begin
Q <= 0;
p <= 0;
end
else if (~Load_1)
begin
if(Q <= moshi - 1)
begin
Q <= Q + 1;
p <= 0;
end
else
begin
Q <= 0;
p <= 1;
end
end
else if (~Stop)
begin
Q <= Q;
p <= p;
end
else if(Q <= moshi - 1)
begin
Q <= Q + 1;
p <= 0;
end
else
begin
Q <= 0;
p <= 1;
end
endmodule
再将该Verilog HDL文件设置为顶层实体,进行编译,有错误则改正。
时位计数模块(Cnt_74161_ss)
module Cnt_74161_ss(H_shi,H_ge,Load_1,
key_1,Clr,Stop,CLK);
input Load_1,key_1,Stop,Clr,CLK;
output H_shi;
reg [3:0] H_shi;
output H_ge;
reg [3:0]H_ge;
assign Tiaojie=(~Load_1)?(~key_1):CLK;
always @(negedge Clr or posedge Tiaojie)
begin
if(~Clr) //清零
begin
H_shi<=8'h00;
H_ge<=8'h00;
end
else if (~Load_1) //Load模式
begin
if((H_shi>=2)&&(H_ge>=3))
begin
H_shi<=8'h00;
H_ge<=8'h00;
end
else if((H_shi==2)&&(H_ge<3))
begin
H_shi<=2;
H_ge<=H_ge+1'b1;
end
else if(H_ge==9)
begin
H_shi<=H_shi+1'b1;
H_ge<=4'b0000;
end
else
begin
H_shi<=H_shi;
H_ge<=H_ge+1'b1;
end
end
else if(~Stop)//暂停模式
begin
H_shi<=H_shi;
H_ge<=H_ge;
end
else if((H_shi>=2)&&(H_ge>=3))
begin
H_shi<=8'h00;
H_ge<=8'h00;
end
else if((H_shi==2)&&(H_ge<3)) //<
begin
H_shi<=2;
H_ge<=H_ge+1'b1;
end
else if(H_ge==9)
begin
H_shi<=H_shi+1'b1;
H_ge<=4'b0000;
end
else
begin
H_shi<=H_shi;
H_ge<=H_ge+1'b1;
end
end
endmodule
再将该Verilog HDL文件设置为顶层实体,进行编译,有错误则改正。
显示模块(scan_led)
module scan_led(clk_1k,Rst_n,d,dig,seg);
input clk_1k;
input Rst_n;
input[31:0] d;
output[7:0] dig;
output[6:0] seg;
reg[7:0] seg_r;
reg[7:0] dig_r;
reg[3:0] disp_dat;
reg[2:0]count;
assign dig = dig_r;
assign seg = seg_r;
always @(posedge clk_1k or negedge Rst_n)
begin
if(~Rst_n)
count <= 3'b000;
else if(count == 3'd7)
count <= 3'b000;
else
count <= count + 1'b1;
end
always @(posedge clk_1k)
begin
case(count)
3'd0:disp_dat = d[23:20];
3'd1:disp_dat = d[19:16];
3'd2:disp_dat = 4'b1010;
3'd3:disp_dat = d[15:12];
3'd4:disp_dat = d[11:8];
3'd5:disp_dat = 4'b1010;
3'd6:disp_dat = d[7:4];
3'd7:disp_dat = d[3:0];
endcase
case(count)
3'd0:dig_r = 8'b0111 1111;
3'd1:dig_r = 8'b1011 1111;
3'd2:dig_r = 8'b1101 1111;
3'd3:dig_r = 8'b1110 1111;
3'd4:dig_r = 8'b1111 0111;
3'd5:dig_r = 8'b1111 1011;
3'd6:dig_r = 8'b1111 1101;
3'd7:dig_r = 8'b1111 1110;
endcase
end
always @(disp_dat)
begin
case(disp_dat)
4'h0:seg_r = 8'hc0;
4'h1:seg_r = 8'hf9;
4'h2:seg_r = 8'ha4;
4'h3:seg_r = 8'hb0;
4'h4:seg_r = 8'h99;
4'h5:seg_r = 8'h92;
4'h6:seg_r = 8'h82;
4'h7:seg_r = 8'hf8;
4'h8:seg_r = 8'h80;
4'h9:seg_r = 8'h90;
4'b1010: seg_r = 8'hbf;
default : seg_r = 8'hff;
endcase
end
endmodule
再将该Verilog HDL文件设置为顶层实体,进行编译,有错误则改正。
消抖模块(debounce)
module debounce(clk_1k,key_in,key_out);
input clk_1k;
input key_in;
output key_out;
reg dout1;
reg dout2;
reg dout3;
assign key_out=(dout1|dout2|dout3);
always@(posedge clk_1k)
begin
dout1<=key_in;
dout2<=dout1;
dout3<=dout2;
end
endmodule
再将该Verilog HDL文件设置为顶层实体,进行编译,有错误则改正。
大顶层模块(LAB_TOP)
module LAB4_TOP(Clk_50,Rst_n,Clr,Stop,key_1,Load_1,Load_2,Load_3,Load_4,Load_5,
dig,seg,led,reset);
input Clk_50;
input Rst_n;
input Clr;
input Stop;
input key_1;
input Load_1;
input Load_2;
input Load_3;
input Load_4;
input Load_5;
input reset;
output[7:0] dig;
output[6:0] seg;
output [7:0] led;
//分频 1Hz 模块调用
wire CLK_1HZ;
ClkDivider #( 25000000) ClkDividerinst1(
.Clk_50(Clk_50),
.Rst_n(Rst_n),
.Clk_div(CLK_1HZ)
);
//分频1KHz 模块调用
wire CLK_1KHZ;
ClkDivider ClkDividerinst2(
.Clk_50(Clk_50),
.Rst_n(Rst_n),
.Clk_div(CLK_1KHZ)
);
wire CLK_2HZ;
ClkDivider #(6250000) ClkDividerinst3(
.Clk_50(Clk_50),
.Rst_n(Rst_n),
.Clk_div(CLK_2HZ)
);
//数码管位选和段选模块调用
scan_led scan_led_inst(
.clk_1k(CLK_1KHZ),
.Rst_n(Rst_n),
.d({8'H0,Q6,Q5,Q4,Q3,Q2,Q1}),
.dig(dig),
.seg(seg));
//秒个位计数模块调用
wire p1;
wire [3:0] Q1;
Cnt_74161_fm Cnt_74161_fm_inst(
.p(p1),
.Q(Q1),
.Load_1(Load_1),
.key_1(oKey),
.CLK(CLK_1HZ),
.Clr(Clr),
.Stop(Stop)
);
//秒十位计数模块调用
wire p2;
wire [3:0] Q2;
Cnt_74161_fm #(5) Cnt_74161_fm_inst1(
.Q(Q2),
.p(p2),
.Load_1(Load_2),
.key_1(oKey),
.CLK(p1),
.Clr(Clr),
.Stop(Stop)
);
//分个位计数模块调用
wire p3;
wire [3:0] Q3;
Cnt_74161_fm #(9) Cnt_74161_fm_inst2(
.Q(Q3),
.p(p3),
.Load_1(Load_3),
.key_1(oKey),
.CLK(p2),
.Clr(Clr),
.Stop(Stop)
);
//分十位计数模块调用
wire p4;
wire [3:0] Q4;
Cnt_74161_fm #(5) Cnt_74161_fm_inst3(
.Q(Q4),
.p(p4),
.Load_1(Load_4),
.key_1(oKey),
.CLK(p3),
.Clr(Clr),
.Stop(Stop)
);
//时位计数模块调用
wire [3:0] Q5;
wire [3:0] Q6;
Cnt_74161_ss Cnt_74161_ss_inst (
.H_shi(Q6),
.H_ge(Q5),
.Load_1(Load_5),
.key_1(oKey),
.CLK(p4),
.Clr(Clr),
.Stop(Stop)
);
//消抖模块模块调用
wire oKey;
debounce (
.clk_1k(CLK_1KHZ),
.key_in(key_1),
.key_out(oKey)
);
endmodule
再将该Verilog HDL文件设置为顶层实体,进行全编译,有错误则改正。
3. 选择目标器件并对相应的引脚进行锁定
引脚分配如图:
4. 进行全编译并找错改错
5. 器件和引脚的其它设置
Device & Options -> Device & Pin Options
在对话框中将其它不相关的引脚设为三态输入以免对芯片造成伤害
6. 再次进行全编译
7. 下载硬件设计到目标FPGA,观察现象并进行相关的调试
五.实验问题及调试:(选取部分进行相关说明)
1. 由于整体实验参照了网络上的资料,在将相关代码拷贝到软件中进行编译工作时,时位计数模块(Cnt_74161_ss)的代码出现了编译错误。
解决方法:根据编译给出的问题提示定位到错误代码所在地方,在理解了代码的意思后进行修改调试,然后再找错,再进行调试,再编译,不断重复执行这几个过程,直到问题得以解决进行下一步。
2. 在将硬件设计下载到目标FPGA上测试时,由于网络资料上使用的芯片和实验室使用的芯片有所不同,所以引脚分配上面也完全不同,产生了很多错误,数字钟无法正常工作。
解决方法:在实验过程中不断参照以前在实验室所做的实验的引脚分配进行调试修改,由于以前做按键实验时所使用的按键个数有限,在实际调试过程中为了实现实验的基本要求对该数字钟的多功能模块进行了相应的取舍,仅保留了清零和暂停功能。(即Load模式相关的引脚没有进行分配)
3. 在解决了引脚不匹配的问题后,又一次将硬件设计下载到目标FPGA上测试时,整个数字钟的显示次序是完全倒置的。
解决方法:经过调试发现出错地方在显示模块(scan_led)中,其中片选 模块出现了错误,片选顺序反了,经过改正后测试无误。
4. 实验过程中还有很多小的错误,就不一一列举了。
六.实验心得:(总结)
通过在之前的基础实验中进行相关的训练练习,我从一开始对Quartus II 软件的不太熟练到现在能够熟练的独立的完成相关的实验,知识也从理论上升到了实际应用层面,刚开始是照搬老师的代码实现功能,现在自己能够修改代码实现不同功能,在实验过程中遇到了很多问题,在请教了老师和同学后现在也能独立的解决相关的基础问题,在调试过程中让人很心烦、思维混乱,但是在耐心的解决问题之后的幸福感和喜悦感是难以言表的,在此过程中提高了自己的兴趣也锻炼了自己的动手能力。虽然本次的数字钟综合实验不完完全全是自己在理解之后自己独立完成的,但是也积累了很多经验学到了很多知识,希望自己能在以后的学习过程中能学到更多的知识积累更多的经验。在此也感谢老师和同学们的帮助,谢谢!
七.附实验顶层的布局图片:
第8 页 共8页
展开阅读全文