基于HDL十进制计数器设计概要.docx
《基于HDL十进制计数器设计概要.docx》由会员分享,可在线阅读,更多相关《基于HDL十进制计数器设计概要.docx(23页珍藏版)》请在冰点文库上搜索。
基于HDL十进制计数器设计概要
FPGA实验
报告二
实验名称:
基于HDL十进制计数器设计
姓名:
学号:
班级:
指导老师:
时间:
2013年3月18日
实验二:
基于HDL十进制计数器设计
一、实验目的
1、掌握基于语言的ISE设计全流程;
2、熟悉、应用VerilogHDL描述数字电路;
3、掌握基于Verilog的组合和时序逻辑电路的设计方法
二、实验要求
1、用HDL语言设计七段显示译码电路,以及十进制加法计数器。
2、要求LED定位显示。
3、完成LED七段码波形的仿真分析
4、在目标板按要求显示译码结果。
三、实验原理
本次试验将完成的设计是一个具有数显输出的十进制计数器。
示意图如2.1所示。
图2.1
七段数码管属于数码管的一种,是由7段二极管组成。
按发光二极管单元衔接方式分为共阳极数码管和共阴极数码管。
本实验使用共阴数码管。
它是指将一切发光二极管的阴极接到一同构成公共阴极(COM)的数码管。
共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平相应字段就点亮,当某一字段的阳极为低电平相应字段就不亮。
显示译码器,用HDL语言判断CLK的上升沿信号,每次收到一次上升沿信号,计数器的值加一并显示在数码管上,所以本次实验会将十进制计数与七段数码管的显示分别写在两个模块里面。
消抖模块,这次不用学生完成,只用在最后的top文件中调用就行。
本实验可以采用ISE软件的HDL语言描述七段数码管的功能与十进制计数功能。
完成的设计是一个具有数显输出的十进制计数器。
四、实验步骤
1、设计准备
(1)设计任务表述:
输入信号:
clk-------待计数的时钟
clr---------异步清零信号,当clr=1,输出复位为0,当clr=0,正常计数
ce---------使能控制信号,当ce=1,电路正常累加计数,否则电路不工作
输出信号:
q[6:
0]---------驱动数码管,显示计数值的个位
cout-----------驱动发光二极管,显示计数值向十位的进位
(2)本实验共包括3个模块:
十进制计数器
驱动七段数码管模块
消抖模块,待计数的时钟clk输入至计数器前,先通过消抖模块。
(3)十进制计数器:
对输入时钟进行计数
输入:
CLK------待计数的时钟
CLR------异步清零信号,当CLR=1,输出复位为0;当CLR=0,正常计数
ENA-------使能控制信号,当ENA=1,电路正常累加计数,否则电路不工作
输出:
SUM[3:
0]----------计数值的个位
COUT----------计数值的十位进位
(4)LED显示驱动模块
输入:
SUM[3:
0]——待显示的数值
OUT[6:
0]——驱动数码管的七位数值
(5)电源按键消抖模块
通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。
因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。
根据实验板的资料,对按键输入信号需进行消抖处理。
电平检查模块:
检测输入的按键是否被按下或者释放,并分别将H2L_Sig,L2H_Sig拉高,并随后拉低,给出按键的操作信息。
延时模块,对输入的信号变化时刻进行计时并观察信号的变换情况,对输出端口进行恰当的赋值。
实验资料中给出消抖模块设计源代码。
消抖模块不要求仿真。
2、十进制计数器TEN_CLK.v的设计
(1)设计输入
1)建立工程:
file->NewProject。
在E盘的根目录下,以学号20105391为文件名建立工程,选择Top-level的类型是HDL
2)正确选择EDA工具与器件
3)建立工程后,开始模块的设计,TEN_CLK.v模块设计。
建立新VerilogHDL模块编辑窗口
4)选择VerilogModule,并输入合法文件名
5)在文本编辑窗口输入代码
以下是我编写十进制计数器的代码:
`timescale1ns/1ps
moduleTen_CLK(CLK,CLR,ENA,ADD,SUM);
inputCLK;
inputENA;
inputCLR;
output[3:
0]SUM;
outputADD;
reg[3:
0]SUM=4'b0000;
regADD=0;
always@(posedgeCLKorposedgeCLR)
begin
if(CLR)
begin
SUM=4'b0000;
ADD=1'b0;
end
else
begin
if(ENA)
if(SUM==4'b1001)
begin
SUM=4'b0000;
ADD=1'b1;
end
else
begin
SUM=SUM+1'b1;
ADD=1'b0;
end
else
begin
SUM=SUM;
ADD=ADD;
end
end
end
endmodule
程序主要思路是用always等待CLK与CLR的上升沿信号,因为是异步清零所以在always中也要等待CLR的清零信号。
用if语句判断CLR信号,为1则清零。
判断ENA信号,为1进行计数操作,为0输出保持不变。
计数中,判断SUM的值如果为9时,进行进位操作,并将SUM值赋值为0。
(2)设计处理
综合:
1)在sources窗口选中待综合模块cnt10,在process窗口双击Synthesize-XST
2)综合完后可以双击Synthesize-XST下的ViewRTLSchematic,得到综合后的电路图。
(3)功能仿真
1)建立仿真激励文件
2)考虑完备性测试和减短仿真耗时,将时钟周期改为100ns,测试文件时间长度2000ns
3)根据所设计的十进制计数器的各种工作状态,完成激励信号的编辑
4)进行仿真:
选择sourcesfor:
BehavioralSimulation
选中激励文件
双击simulateBehavioralModel
5)分析得到的仿真波形,如有问题,对设计进行修正。
由于本次设计的时钟周期长,对时序没有要求,故可以省略各子模块的时序仿真。
3、LED驱动模块LED_Ten.v的设计
(1)分析理解七段数码管的真值表,完成输入输出的转换
(2)与TEN_CLK.v的设计步骤相同,完成这个模块的设计输入综合、功能、仿真。
下面我主要介绍代码的思路与我写的代码以及激励文件截图和仿真。
`timescale1ns/1ps
moduleLED_Ten(data_in,data_out);
input[3:
0]data_in;
output[6:
0]data_out;
reg[6:
0]data_out;
always@(data_in)
begin
begin
case(data_in)
4'b0000:
data_out<=7'b1111110;
4'b0001:
data_out<=7'b0110000;
4'b0010:
data_out<=7'b1101101;
4'b0011:
data_out<=7'b1111001;
4'b0100:
data_out<=7'b0110011;
4'b0101:
data_out<=7'b1011011;
4'b0110:
data_out<=7'b1011111;
4'b0111:
data_out<=7'b1110000;
4'b1000:
data_out<=7'b1111111;
4'b1001:
data_out<=7'b1111011;
4'b1010:
data_out<=7'b1110111;
4'b1011:
data_out<=7'b0011111;
4'b1100:
data_out<=7'b1001110;
4'b1101:
data_out<=7'b0111101;
4'b1110:
data_out<=7'b1001111;
default:
data_out<=7'b1000111;
endcase
end
end
endmodule
代码本身思路很简单,用一个case语句判断输入的data_in的值,选择data_out的输出,这样比用原理图设计数码管要大大的减少工作量。
激励文件:
仿真结果:
4、消抖模块设计
(1)了解消抖模块的功能,拷贝相关代码
(2)拟采用实验板上的50MHZ时钟为延迟计数时钟
(3)为设计简单,cnt10模块中的复位信号和使能信号通过拨动开关输入,仅有做时钟的按键信号通过消抖模块处理
(4)消抖模块的复位信号、使能信号与cnt10模块共用
5、顶层模块设计
(1)用verilogHDL代码描述模块的连接,构成如下图所示的系统:
`timescale1ns/1ps
moduletop_LED(clk_50,clk,clr,ena,cout,data_Out);
inputclk,clr,ena,clk_50;
outputcout;
output[6:
0]data_Out;
wire[3:
0]temp;
Ten_CLKU1(Pin_Out,clr,ena,cout,temp);
LED_TenU2(temp,data_Out);
debounce_moduleU3(clk_50,clk,clr,Pin_Out);
endmodule
顶层模块的代码并不复杂,主要注意调用各个模块,并对其的连线不能出错,综合以后出现下图,如与符合要求就继续进行之后的操作。
(2)HDL代码完成后,综合,功能仿真,分析仿真波形,修正代码,确认设计正确。
(3)引脚锁定:
由于clk没锁于默认的时钟输入引脚上,需在生成的约束文件(.ucf)中clk的锁定改为:
NET"clk"LOC="K16"|CLOCK_DEDICATED_ROUTE=FALSE;
或另加一行:
NET"clk"CLOCK_DEDICATED_ROUTE=FALSE;
(4)双击ImplementDesign,进行布局布线
(5)进行时序仿真
激励文件:
仿真文件:
(6)分析波形,修正设计,直至设计正确。
6、下载
(1)双击GenerateProgrammingFile生成下载文件
(2)双击ConfigureTargetDevice
(3)点击OK,点击Finish
(4)对随后的两个器件,一个是Prom,一个是CPLD,选择Bypass
(5)弹出对话框,点击OK
(6)下载后,改变波动开关盒按键,观察结果
五、思考题
1、如何用两个或一个always实现十进制计数模块?
写出相应代码。
一个always如下:
always@(posedgeCLKorposedgeCLR)
begin
if(CLR)
begin
SUM=4'b0000;
ADD=1'b0;
end
else
begin
if(ENA)
if(SUM==4'b1001)
begin
SUM=4'b0000;
ADD=1'b1;
end
else
begin
SUM=SUM+1'b1;
ADD=1'b0;
end
else
begin
SUM=SUM;
ADD=ADD;
end
end
end
endmodule
两个always如下:
always@(CLR)
begin
if(CLR)
flag=1;
else
flag=0;
end
always@(posedgeCLK)
begin
if(flag)
begin
SUM=4'b0000;
ADD=1'b0;
end
else
begin
if(ENA)
if(SUM==4'b1001)
begin
SUM=4'b0000;
ADD=1'b1;
end
else
begin
SUM=SUM+1'b1;
ADD=1'b0;
end
else
begin
SUM=SUM;
ADD=ADD;
end
end
end
endmodule
2、如何用always,或assign实现数码管的驱动设计?
写出相应代码
always如下:
always@(data_in)
begin
begin
case(data_in)
4'b0000:
data_out<=7'b1111110;
4'b0001:
data_out<=7'b0110000;
4'b0010:
data_out<=7'b1101101;
4'b0011:
data_out<=7'b1111001;
4'b0100:
data_out<=7'b0110011;
4'b0101:
data_out<=7'b1011011;
4'b0110:
data_out<=7'b1011111;
4'b0111:
data_out<=7'b1110000;
4'b1000:
data_out<=7'b1111111;
4'b1001:
data_out<=7'b1111011;
4'b1010:
data_out<=7'b1110111;
4'b1011:
data_out<=7'b0011111;
4'b1100:
data_out<=7'b1001110;
4'b1101:
data_out<=7'b0111101;
4'b1110:
data_out<=7'b1001111;
default:
data_out<=7'b1000111;
endcase
end
end
assign如下:
感觉很复杂,像是直观的门电路的与非描述,暂时还没有想出比较简单的方法。
3、比较实验一与实验二的实验过程,说明原理图输入法与HDL输入法的不同的应用环境
答:
实验一中应用的是原理图完成十进制计数器的数显,工作量相对较大,需要绘制8张原理图,其中还不包括消抖模块。
所以,原理图设计适合相对简单的电路,门电路较少的电路。
而实验二中应用HDL语言描述要完成的功能,对于较复杂的电路设计起来相对简单,所以HDL设计适合比较复杂的电路。
门电路很多的电路。
六、实验体会
通过这次实验,初步对应用HDL描述与设计时序和组合电路有了一定程度的掌握,熟悉了应用ISE软件的操作流程,掌握了用代码完成仿真,综合,下载等操作。
可惜的是在最后下载程序中,总是不能把程序下载到开发板中。
另外,我深刻体会到需要用更多的时间来练习才能完成更复杂的电路设计。
最后,也是最重要的是在设计一个电路之前,设计准备很重要,弄懂有多少个输入口输出口。
怎样用算法实现各个功能,考虑好各种情况,比如这次就要考虑到消抖的情况。