verilog计数器实验报告.docx

上传人:b****8 文档编号:12437932 上传时间:2023-06-05 格式:DOCX 页数:19 大小:637.23KB
下载 相关 举报
verilog计数器实验报告.docx_第1页
第1页 / 共19页
verilog计数器实验报告.docx_第2页
第2页 / 共19页
verilog计数器实验报告.docx_第3页
第3页 / 共19页
verilog计数器实验报告.docx_第4页
第4页 / 共19页
verilog计数器实验报告.docx_第5页
第5页 / 共19页
verilog计数器实验报告.docx_第6页
第6页 / 共19页
verilog计数器实验报告.docx_第7页
第7页 / 共19页
verilog计数器实验报告.docx_第8页
第8页 / 共19页
verilog计数器实验报告.docx_第9页
第9页 / 共19页
verilog计数器实验报告.docx_第10页
第10页 / 共19页
verilog计数器实验报告.docx_第11页
第11页 / 共19页
verilog计数器实验报告.docx_第12页
第12页 / 共19页
verilog计数器实验报告.docx_第13页
第13页 / 共19页
verilog计数器实验报告.docx_第14页
第14页 / 共19页
verilog计数器实验报告.docx_第15页
第15页 / 共19页
verilog计数器实验报告.docx_第16页
第16页 / 共19页
verilog计数器实验报告.docx_第17页
第17页 / 共19页
verilog计数器实验报告.docx_第18页
第18页 / 共19页
verilog计数器实验报告.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

verilog计数器实验报告.docx

《verilog计数器实验报告.docx》由会员分享,可在线阅读,更多相关《verilog计数器实验报告.docx(19页珍藏版)》请在冰点文库上搜索。

verilog计数器实验报告.docx

verilog计数器实验报告

计数器

1、实现目标及介绍

实验实现了一个简易的计数器,计数范围可达899(0~899),通过key4按键计数,每按下一次,计数加一,百位数显示在led上,个位与十位显示在数码管上。

为十进制计数,数码管1计数到九后置零。

数码管2获得进位加一,数码管2到9后当再次获得个位进位时再次向百位进一,点亮led1,每百位点亮一个led。

此外key4为清零键,可随时按键清零。

2、效果展示

计数99

 

清零

计数100

 

视频展示(双击观看)

 

3、代码实现与模块分析

1.顶层模块

modulejishuqi

inputwireclk,rst,//时钟和复位输入

inputwirekey1,//拨码计

outputwire[7:

0]led,

outputwire[8:

0]segment_led_1,segment_led_2//数码管输出

);

wirekey_pulse;

reg[7:

0]cnt;//计时计数器

reg[7:

0]hud;//百位计数

initialhud[7:

0]<=8'b11111111;

always@(posedgeclkornegedgerst)

begin//数码管显示要按照十进制的方式显示

if(!

rst)

begincnt<=8'h00;

hud[7:

0]<=8'b11111111;

end

elseif(key_pulse)

begin

if(cnt[3:

0]==4'd9)//个位进位判断

begin

cnt[3:

0]<=4'd0;

if(cnt[7:

4]==4'd9)//十位进位判断

begin

cnt[7:

4]<=4'd0;

hud[7:

0]<=hud[7:

0]-1'b1;

end

else

cnt[7:

4]<=cnt[7:

4]+1'b1;

end

elsecnt[3:

0]<=cnt[3:

0]+1'b1;

end

else

cnt<=cnt;

end

assignled=hud;

//例化调用数码管显示模块

segmentu2

.seg_data_1(cnt[7:

4]),//g_datainput

.seg_data_2(cnt[3:

0]),//g_datainput

.seg_led_1(segment_led_1),//MSB~LSB=SEG,DP,G,F,E,D,C,B,A

.seg_led_2(segment_led_2)//MSB~LSB=SEG,DP,G,F,E,D,C,B,A

);

//例化调用消抖模块

debounceu1(

.clk(clk),

.rst(rst),

.key(key1),

.key_pulse(key_pulse)

);

endmodule

2.数码管显示模块

modulesegment(seg_data_1,seg_data_2,seg_led_1,seg_led_2);

input[3:

0]seg_data_1;//数码管需要显示0~9十个数字,所以最少需要4位输入做译码

input[3:

0]seg_data_2;//小脚丫上第二个数码管

output[8:

0]seg_led_1;//在小脚丫上控制一个数码管需要9个信号MSB~LSB=DIG、DP、G、F、E、D、C、B、A

output[8:

0]seg_led_2;//在小脚丫上第二个数码管的控制信号MSB~LSB=DIG、DP、G、F、E、D、C、B、A

reg[8:

0]seg[9:

0];

//定义了一个reg型的数组变量,相当于一个10*9的存储器,存储器一共有10个数,每个数有9位宽

initial

//在过程块中只能给reg型变量赋值,Verilog中有两种过程块always和initial

//initial和always不同,其中语句只执行一次

begin

seg[0]=9'h3f;//对存储器中第一个数赋值9'b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字0

seg[1]=9'h06;//7段显示数字1

seg[2]=9'h5b;//7段显示数字2

seg[3]=9'h4f;//7段显示数字3

seg[4]=9'h66;//7段显示数字4

seg[5]=9'h6d;//7段显示数字5

seg[6]=9'h7d;//7段显示数字6

seg[7]=9'h07;//7段显示数字7

seg[8]=9'h7f;//7段显示数字8

seg[9]=9'h6f;//7段显示数字9

end

assignseg_led_1=seg[seg_data_1];//连续赋值,这样输入不同四位数,就能输出对于译码的9位输出

assignseg_led_2=seg[seg_data_2];

endmodule

3.按键消抖模块

//按键消抖

moduledebounce(clk,rst,key,key_pulse);

parameterN=2;//要消除的按键的数量

inputclk;

inputrst;

input[N-1:

0]key;//输入的按键

output[N-1:

0]key_pulse;//按键动作产生的脉冲

reg[N-1:

0]key_rst_pre;//定义一个寄存器型变量存储上一个触发时的按键值

reg[N-1:

0]key_rst;//定义一个寄存器变量储存储当前时刻触发的按键值

wire[N-1:

0]key_edge;//检测到按键由高到低变化是产生一个高脉冲

//利用非阻塞赋值特点,将两个时钟触发时按键状态存储在两个寄存器变量中

always@(posedgeclkornegedgerst)

begin

if(!

rst)

begin

key_rst<={N{1'b1}};//初始化时给key_rst赋值全为1,{}中表示N个1

key_rst_pre<={N{1'b1}};

end

else

begin

key_rst<=key;//第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_pre

key_rst_pre<=key_rst;//非阻塞赋值。

相当于经过两个时钟触发,key_rst存储的是当前时刻key的值,key_rst_pre存储的是前一个时钟的key的值

end

end

assignkey_edge=key_rst_pre&(~key_rst);//脉冲边沿检测。

当key检测到下降沿时,key_edge产生一个时钟周期的高电平

reg[17:

0]cnt;//产生延时所用的计数器,系统时钟12MHz,要延时20ms左右时间,至少需要18位计数器

//产生20ms延时,当检测到key_edge有效是计数器清零开始计数

always@(posedgeclkornegedgerst)

begin

if(!

rst)

cnt<=18'h0;

elseif(key_edge)

cnt<=18'h0;

else

cnt<=cnt+1'h1;

end

reg[N-1:

0]key_sec_pre;//延时后检测电平寄存器变量

reg[N-1:

0]key_sec;

//延时后检测key,如果按键状态变低产生一个时钟的高脉冲。

如果按键状态是高的话说明按键无效

always@(posedgeclkornegedgerst)

begin

if(!

rst)

key_sec<={N{1'b1}};

elseif(cnt==18'h3ffff)

key_sec<=key;

end

always@(posedgeclkornegedgerst)

begin

if(!

rst)

key_sec_pre<={N{1'b1}};

else

key_sec_pre<=key_sec;

end

assignkey_pulse=key_sec_pre&(~key_sec);

endmodule

 

4、源码与源码图片

modulejishuqi

inputwireclk,rst,//时钟和复位输入

inputwirekey1,//拨码计

outputwire[7:

0]led,

outputwire[8:

0]segment_led_1,segment_led_2//数码管输出

);

wirekey_pulse;

reg[7:

0]cnt;//计时计数器

reg[7:

0]hud;//百位计数

initialhud[7:

0]<=8'b11111111;

always@(posedgeclkornegedgerst)

begin//数码管显示要按照十进制的方式显示

if(!

rst)

begincnt<=8'h00;

hud[7:

0]<=8'b11111111;

end

elseif(key_pulse)

begin

if(cnt[3:

0]==4'd9)

begin

cnt[3:

0]<=4'd0;

if(cnt[7:

4]==4'd9)

begin

cnt[7:

4]<=4'd0;

hud[7:

0]<=hud[7:

0]-1'b1;

end

else

cnt[7:

4]<=cnt[7:

4]+1'b1;

end

elsecnt[3:

0]<=cnt[3:

0]+1'b1;

end

else

cnt<=cnt;

end

assignled=hud;

segmentu2

.seg_data_1(cnt[7:

4]),//g_datainput

.seg_data_2(cnt[3:

0]),//g_datainput

.seg_led_1(segment_led_1),//MSB~LSB=SEG,DP,G,F,E,D,C,B,A

.seg_led_2(segment_led_2)//MSB~LSB=SEG,DP,G,F,E,D,C,B,A

);

debounceu1(

.clk(clk),

.rst(rst),

.key(key1),

.key_pulse(key_pulse)

);

endmodule

//按键消抖

moduledebounce(clk,rst,key,key_pulse);

parameterN=2;//要消除的按键的数量

inputclk;

inputrst;

input[N-1:

0]key;//输入的按键

output[N-1:

0]key_pulse;//按键动作产生的脉冲

reg[N-1:

0]key_rst_pre;//定义一个寄存器型变量存储上一个触发时的按键值

reg[N-1:

0]key_rst;//定义一个寄存器变量储存储当前时刻触发的按键值

wire[N-1:

0]key_edge;//检测到按键由高到低变化是产生一个高脉冲

//利用非阻塞赋值特点,将两个时钟触发时按键状态存储在两个寄存器变量中

always@(posedgeclkornegedgerst)

begin

if(!

rst)

begin

key_rst<={N{1'b1}};//初始化时给key_rst赋值全为1,{}中表示N个1

key_rst_pre<={N{1'b1}};

end

else

begin

key_rst<=key;//第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_pre

key_rst_pre<=key_rst;//非阻塞赋值。

相当于经过两个时钟触发,key_rst存储的是当前时刻key的值,key_rst_pre存储的是前一个时钟的key的值

end

end

assignkey_edge=key_rst_pre&(~key_rst);//脉冲边沿检测。

当key检测到下降沿时,key_edge产生一个时钟周期的高电平

reg[17:

0]cnt;//产生延时所用的计数器,系统时钟12MHz,要延时20ms左右时间,至少需要18位计数器

//产生20ms延时,当检测到key_edge有效是计数器清零开始计数

always@(posedgeclkornegedgerst)

begin

if(!

rst)

cnt<=18'h0;

elseif(key_edge)

cnt<=18'h0;

else

cnt<=cnt+1'h1;

end

reg[N-1:

0]key_sec_pre;//延时后检测电平寄存器变量

reg[N-1:

0]key_sec;

//延时后检测key,如果按键状态变低产生一个时钟的高脉冲。

如果按键状态是高的话说明按键无效

always@(posedgeclkornegedgerst)

begin

if(!

rst)

key_sec<={N{1'b1}};

elseif(cnt==18'h3ffff)

key_sec<=key;

end

always@(posedgeclkornegedgerst)

begin

if(!

rst)

key_sec_pre<={N{1'b1}};

else

key_sec_pre<=key_sec;

end

assignkey_pulse=key_sec_pre&(~key_sec);

endmodule

modulesegment(seg_data_1,seg_data_2,seg_led_1,seg_led_2);

input[3:

0]seg_data_1;//数码管需要显示0~9十个数字,所以最少需要4位输入做译码

input[3:

0]seg_data_2;//小脚丫上第二个数码管

output[8:

0]seg_led_1;//在小脚丫上控制一个数码管需要9个信号MSB~LSB=DIG、DP、G、F、E、D、C、B、A

output[8:

0]seg_led_2;//在小脚丫上第二个数码管的控制信号MSB~LSB=DIG、DP、G、F、E、D、C、B、A

reg[8:

0]seg[9:

0];

//定义了一个reg型的数组变量,相当于一个10*9的存储器,存储器一共有10个数,每个数有9位宽

initial

//在过程块中只能给reg型变量赋值,Verilog中有两种过程块always和initial

//initial和always不同,其中语句只执行一次

begin

seg[0]=9'h3f;//对存储器中第一个数赋值9'b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字0

seg[1]=9'h06;//7段显示数字1

seg[2]=9'h5b;//7段显示数字2

seg[3]=9'h4f;//7段显示数字3

seg[4]=9'h66;//7段显示数字4

seg[5]=9'h6d;//7段显示数字5

seg[6]=9'h7d;//7段显示数字6

seg[7]=9'h07;//7段显示数字7

seg[8]=9'h7f;//7段显示数字8

seg[9]=9'h6f;//7段显示数字9

end

assignseg_led_1=seg[seg_data_1];//连续赋值,这样输入不同四位数,就能输出对于译码的9位输出

assignseg_led_2=seg[seg_data_2];

endmodule

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2