回答

收藏

刚开始系统学习FPGA

Raspberry Pi Raspberry Pi 2565 人阅读 | 0 人回复 | 2017-02-27

刚开始系统学习FPGA,写了一个带按键消抖的按键数码管计数器,但是有一个问题,复位以后数码管显示的不是0,是1,有点不理解。
贴代码:
`timescale 1ns / 1ps
module prj_keyseg
(
        //输入端口
        clk,rst_n,key,
        //输出端口
        SEG_DATA,SEG_EN
);

//---------------------------------------------------------------------------
//--        外部端口声明
//---------------------------------------------------------------------------
input                                        clk;                                //时钟的端口,开发板用的50MHz晶振
input                                        rst_n;                                //复位的端口,低电平复位
input                key;                                        //对应开发板上的key
output           SEG_EN;                                //数码管使能端口
output                  [6:0]SEG_DATA;                        //数码管数据端口(查看管脚分配文档或者原理图)

//--------------------------------------------------------------------------
//----按键消抖程序
//--------------------------------------------------------------------------

reg key_rst;  

always @(posedge clk  or negedge rst_n)
    if (!rst_n) key_rst <= 1'b1;
    else key_rst <= key;

reg key_rst_r;      

always @ ( posedge clk  or negedge rst_n )
    if (!rst_n) key_rst_r <= 1'b1;
    else key_rst_r <= key_rst;

//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire key_an = key_rst_r & ( ~key_rst);

//---------------------------------------------------------------------------
reg[19:0]  cnt;        //计数寄存器

always @ (posedge clk  or negedge rst_n)
    if (!rst_n) cnt <= 20'd0;        //异步复位
        else if(key_an) cnt <=20'd0;
    else cnt <= cnt + 1'b1;

reg low_sw;

always @(posedge clk  or negedge rst_n)
    if (!rst_n) low_sw <= 1'b1;
    else if (cnt == 20'hfffff)         //满20ms,将按键值锁存到寄存器low_sw中         cnt == 20'hfffff
      low_sw <= key;

//---------------------------------------------------------------------------
reg   low_sw_r;      

always @ ( posedge clk  or negedge rst_n )
    if (!rst_n) low_sw_r <= 1'b1;
    else low_sw_r <= low_sw;

//当寄存器low_sw由1变为0时,seg_ctrl的值变为高,维持一个时钟周期
wire seg_ctrl = low_sw_r & ( ~low_sw);
reg[3:0] num;        //显示数值

always @ (posedge clk or negedge rst_n)
        if(!rst_n) num <= 4'h0;   //复位数字清零
        else if(seg_ctrl)
                        begin
                                if(num<4'h9) num<=num+1'd1;    //按键按一次,数码管加一
                                else num<=4'h0;
                        end
//-------------------------------------------------------------------------------
/*        共阴极 :不带小数点
              ;0,  1,  2,  3,  4, 5,  6,  7,  
      db      3fh,06h,5bh,4fh,66h,6dh,7dh,07h
              ;8,  9, a,  b,   c,  d,  e,  f , 灭   
      db      7fh,6fh,77h,7ch,39h,5eh,79h,71h,00h*/
parameter        seg0        = 7'h3f,
                        seg1        = 7'h06,
                        seg2        = 7'h5b,
                        seg3        = 7'h4f,
                        seg4        = 7'h66,
                        seg5        = 7'h6d,
                        seg6        = 7'h7d,
                        seg7        = 7'h07,
                        seg8        = 7'h7f,
                        seg9        = 7'h6f;
               

reg[6:0] SEG_DATAR;                //7段数码管(不包括小数点)

always @ (num)
                case (num)        //NUM值显示在两个数码管上
                        4'h0: SEG_DATAR <= seg0;
                        4'h1: SEG_DATAR <= seg1;
                        4'h2: SEG_DATAR <= seg2;
                        4'h3: SEG_DATAR <= seg3;
                        4'h4: SEG_DATAR <= seg4;
                        4'h5: SEG_DATAR <= seg5;
                        4'h6: SEG_DATAR <= seg6;
                        4'h7: SEG_DATAR <= seg7;
                        4'h8: SEG_DATAR <= seg8;
                        4'h9: SEG_DATAR <= seg9;
                        default: ;
                        endcase
assign SEG_DATA = SEG_DATAR;
assign SEG_EN = 1'b0;                //数码管常开
endmodule
分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条