经典的verilog键盘程序.doc
文本预览下载声明
经典的verilog键盘扫描程序
作者: HYPERLINK /ilove314/ \t _blank ilove314
拿到威百仕( VibesIC )的板子后就迫不及待的开始我的学习计划,从最基础的分频程序开始,但看到这个键盘扫描程序后,直呼经典,有相见恨晚的感觉,还想说一句:威百仕( VibesIC ),我很看好你!WHY?待我慢慢道来,这个程序的综合后是0error,0warning。想想自己编码的时候那个warning是满天飞,现在才明白HDL设计有那么讲究了,代码所设计的不仅仅是简单的逻辑以及时序的关系,更重要的是你要在代码中要表现出每一个寄存器,甚至每一个走线。想想我写过的代码,只注意到了前者,从没有注意过后者,还洋洋自得以为自己也算是个高手了,现在想来,实在惭愧啊!学习学习在学习,这也重新激发了我对HDL设计的激情,威百仕给了我一个方向,那我可要开始努力喽!
废话说了一大堆,看程序吧:(本代码经过ise7.1i综合并下载到SP306板上验证通过)
//当三个独立按键的某一个被按下后,相应的LED被点亮;再次按下后,LED熄灭,按键控制LED亮灭
module key_debounce(
clk,rst_n,s1_n,s2_n,s3_n,s4_n,s5_n,led_d1,led_d2,led_d3,led_d4,led_d5);
input clk; //主时钟信号,10MHz
input rst_n; //复位信号,低有效
input s1_n,s2_n,s3_n,s4_n,s5_n;
output led_d1,led_d2,led_d3,led_d4,led_d5;
reg[4:0] s_rst;
always @(posedge clk or negedge rst_n)
if (!rst_n) s_rst = 5b11111;
else s_rst = {s5_n,s4_n,s3_n,s2_n,s1_n};
reg[4:0] s_rst_r;
always @ ( posedge clk or negedge rst_n )
if (!rst_n) s_rst_r = 5b11111;
else s_rst_r = s_rst;
wire[4:0] s_an = s_rst_r ( ~s_rst);
reg[19:0] cnt; //计数寄存器
always @ (posedge clk or negedge rst_n)
if (!rst_n) cnt = 20d0; //异步复位
else if(s_an) cnt =20d0;
else cnt = cnt + 1b1;
reg[4:0] low_s;
always @(posedge clk or negedge rst_n)
if (!rst_n) low_s = 5b11111;
else if (cnt == 20h30D40)
low_s = {s5_n,s4_n,s3_n,s2_n,s1_n};
reg [4:0] low_s_r;
always @ ( posedge clk or negedge rst_n )
if (!rst_n) low_s_r = 5b11111;
else low_s_r = low_s;
wire[4:0] led_ctrl = low_s_r[4:0] ( ~low_s[4:0]);
reg d1,d2,d3,d4,d5;
always @ (posedge clk or negedge rst_n)
if (!rst_n) begin
d1 = 1b0;
d2 = 1b0;
d3 = 1b0;
d4 = 1b0;
d5 = 1b0; end
else begin //
if ( led_ctrl[0] ) d1 = ~d1;
if ( led_ctrl[1] ) d2 = ~d2;
if ( led_ctrl[2] ) d3 = ~d3;
if ( led_ctrl[3] ) d4 = ~d4;
if ( led_ctrl[4] ) d5 = ~d5; end
assign led_d1 = d1 ? 1b1 : 1b0; //LED翻转输出
assign led_d2
显示全部