Verilog實(shí)現(xiàn)按鍵計(jì)數(shù)器
一、簡(jiǎn)介
計(jì)數(shù)器我們都知道,這里我們旨在使用Verilog HDL 來(lái)實(shí)現(xiàn)按鍵計(jì)數(shù)器的操作,功能有:
1、按下一個(gè)鍵,計(jì)數(shù)加一(+1);
2、按下另一個(gè)鍵,計(jì)數(shù)減一(-1);
3、按下復(fù)位鍵,則計(jì)數(shù)清零。
4、最多計(jì)數(shù)60次。
二、 代碼實(shí)現(xiàn)
我們使用了兩個(gè)模塊,第一個(gè)是按鍵消抖模塊,第二個(gè)是實(shí)現(xiàn)計(jì)數(shù)器的功能。因?yàn)椋覀兌贾?,用按鍵,必消抖。
1、按鍵消抖模塊:
// ********************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ********************************************************************
// File name : debounce.v
// Module name : debounce
// Author : STEP
// Description :
// Web : www.stepfpga.com
//
// --------------------------------------------------------------------
// Code Revision History :
// --------------------------------------------------------------------
// Version: |Mod. Date: |Changes Made:
// V1.0 |2017/03/02 |Initial ver
// --------------------------------------------------------------------
// Module Function:按鍵消抖
module debounce_button (clk,rst,key,key_pulse);
parameter N = 1; //要消除的按鍵的數(shù)量
input clk;
input rst;
input [N-1:0] key; //輸入的按鍵
output [N-1:0] key_pulse; //按鍵動(dòng)作產(chǎn)生的脈沖
reg [N-1:0] key_rst_pre; //定義一個(gè)寄存器型變量存儲(chǔ)上一個(gè)觸發(fā)時(shí)的按鍵值
reg [N-1:0] key_rst; //定義一個(gè)寄存器變量?jī)?chǔ)存儲(chǔ)當(dāng)前時(shí)刻觸發(fā)的按鍵值
wire [N-1:0] key_edge; //檢測(cè)到按鍵由高到低變化是產(chǎn)生一個(gè)高脈沖
//利用非阻塞賦值特點(diǎn),將兩個(gè)時(shí)鐘觸發(fā)時(shí)按鍵狀態(tài)存儲(chǔ)在兩個(gè)寄存器變量中
always @(posedge clk or negedge rst)
begin
if (!rst) begin
key_rst <= {N{1'b1}}; //初始化時(shí)給key_rst賦值全為1,{}中表示N個(gè)1
key_rst_pre <= {N{1'b1}};
end
else begin
key_rst <= key; //第一個(gè)時(shí)鐘上升沿觸發(fā)之后key的值賦給key_rst,同時(shí)key_rst的值賦給key_rst_pre
key_rst_pre <= key_rst; //非阻塞賦值。相當(dāng)于經(jīng)過(guò)兩個(gè)時(shí)鐘觸發(fā),key_rst存儲(chǔ)的是當(dāng)前時(shí)刻key的值,key_rst_pre存儲(chǔ)的是前一個(gè)時(shí)鐘的key的值
end
end
assign key_edge = key_rst_pre & (~key_rst);//脈沖邊沿檢測(cè)。當(dāng)key檢測(cè)到下降沿時(shí),key_edge產(chǎn)生一個(gè)時(shí)鐘周期的高電平
reg [17:0] cnt; //產(chǎn)生延時(shí)所用的計(jì)數(shù)器,系統(tǒng)時(shí)鐘12MHz,要延時(shí)20ms左右時(shí)間,至少需要18位計(jì)數(shù)器
//產(chǎn)生20ms延時(shí),當(dāng)檢測(cè)到key_edge有效是計(jì)數(shù)器清零開(kāi)始計(jì)數(shù)
always @(posedge clk or negedge rst)
begin
if(!rst)
cnt <= 18'h0;
else if(key_edge)
cnt <= 18'h0;
else
cnt <= cnt + 1'h1;
end
reg [N-1:0] key_sec_pre; //延時(shí)后檢測(cè)電平寄存器變量
reg [N-1:0] key_sec;
//延時(shí)后檢測(cè)key,如果按鍵狀態(tài)變低產(chǎn)生一個(gè)時(shí)鐘的高脈沖。如果按鍵狀態(tài)是高的話說(shuō)明按鍵無(wú)效
always @(posedge clk or negedge rst)
begin
if (!rst)
key_sec <= {N{1'b1}};
else if (cnt==18'h3ffff)
key_sec <= key;
end
always @(posedge clk or negedge rst)
begin
if (!rst)
key_sec_pre <= {N{1'b1}};
else
key_sec_pre <= key_sec;
end
assign key_pulse = key_sec_pre & (~key_sec);
endmodule
2、按鍵計(jì)數(shù)器的模塊:
module btncounter(clk,rst, btn1, btn2,seg_led_1,seg_led_2);
input clk;
input rst;
input btn1;
input btn2;
// input [3:0] seg_data_1;
//數(shù)碼管需要顯示0~9十個(gè)數(shù)字,所以最少需要4位輸入做譯碼
// input [3:0] seg_data_2;
output [8:0] seg_led_1;
//在小腳丫上控制一個(gè)數(shù)碼管需要9個(gè)信號(hào) MSB~LSB=DIG、DP、G、F、E、D、C、B、A
output [8:0] seg_led_2;
//在小腳丫上第二個(gè)數(shù)碼管的控制信號(hào) MSB~LSB=DIG、DP、G、F、E、D、C、B、A
reg [8:0] seg [9:0];
//定義了一個(gè)reg型的數(shù)組變量,相當(dāng)于一個(gè)10*9的存儲(chǔ)器,存儲(chǔ)器一共有10個(gè)數(shù),每個(gè)數(shù)有9位寬
wire key_pulse1;
wire key_pulse2;
reg [5:0] counting = 2'd00;
reg [3:0] seg_data_1= 1'd0;
reg [3:0] seg_data_2= 1'd0;
initial
//在過(guò)程塊中只能給reg型變量賦值,Verilog中有兩種過(guò)程塊always和initial
begin
seg[0] = 9'h3f;
//對(duì)存儲(chǔ)器中第一個(gè)數(shù)賦值9'b00_0011_1111,相當(dāng)于共陰極接地,DP點(diǎn)變低不亮,7段顯示數(shù)字 0
seg[1] = 9'h06;
//7段顯示數(shù)字 1
seg[2] = 9'h5b;
//7段顯示數(shù)字 2
seg[3] = 9'h4f;
//7段顯示數(shù)字 3
seg[4] = 9'h66;
//7段顯示數(shù)字 4
seg[5] = 9'h6d;
//7段顯示數(shù)字 5
seg[6] = 9'h7d;
//7段顯示數(shù)字 6
seg[7] = 9'h07;
//7段顯示數(shù)字 7
seg[8] = 9'h7f;
//7段顯示數(shù)字 8
seg[9] = 9'h6f;
//7段顯示數(shù)字 9
end
debounce_button u1 (
.clk (clk),
.rst (rst),
.key (btn1),
.key_pulse (key_pulse1)
);
//按鍵1對(duì)應(yīng)于加一
debounce_button u2 (
.clk (clk),
.rst (rst),
.key (btn2),
.key_pulse (key_pulse2)
);
//按鍵2對(duì)應(yīng)于減一
always@(posedge clk or negedge rst)
begin
if(~rst)
begin
counting <= 0;
end
else
begin
if(key_pulse1)
begin
counting <= (counting + 1) % 60;
end
else
begin
if(key_pulse2)
begin
counting <= (counting -1 + 60) % 60;
end
else
begin
counting <= counting;
end
end
seg_data_1 <= counting / 10;
if(counting % 10 == 0)
begin
seg_data_2 <= 0;
end
else
begin
seg_data_2 <= counting - 10 * seg_data_1;
end
end
end
assign seg_led_1 = seg[seg_data_1];
assign seg_led_2 = seg[seg_data_2];
endmodule
然后進(jìn)行,設(shè)置引腳以及燒錄:
三、效果
我們使用如下所示的視頻來(lái)展示具體的效果:
https://www.bilibili.com/video/BV1f34y1R7Wm?spm_id_from=333.999.0.0
按鍵計(jì)數(shù)器的視頻文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-445076.html
以上就是使用Verilog HDL來(lái)實(shí)現(xiàn)計(jì)數(shù)器的功能的基本操作了,如果有幫助的話就點(diǎn)個(gè)贊吧,謝謝大家的閱讀與支持了啦,(づ ̄3 ̄)づ╭?~。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-445076.html
到了這里,關(guān)于Verilog實(shí)現(xiàn)按鍵計(jì)數(shù)器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!