多个按键控制小灯

顶层模块

module key_filter_led
 (
    input wire CLK,
    input wire RST,
    
    input wire [2:0] KEY,
    
    output wire [3:0] LED
  );

wire [2:0] FLAG;
wire [2:0] KEY_VALUE;

key_filter u_key_filter
(
   .clk      (CLK),
   .rst      (RST),
            
   .key      (KEY),
   .flag     (FLAG),//判断
   .key_value(KEY_VALUE) //消抖后的key

);

led u_led
(
   . clk     (CLK),
   . rst     (RST),
   .flag     (FLAG),
   .key_value(KEY_VALUE),
             
   . led     (LED)
);
endmodule

按键消抖模块

module key_filter
(
   input clk,
   input rst,
   
   input  wire [2:0] key,
   output reg [2:0] flag,//判断
   //output reg key_value //消抖后的key
   output reg [2:0]  key_value //消抖后的key,多个按键消抖
);
parameter delay=20'd999_999;//10ms
reg [19:0] delay_cnt;//延时计数器
reg [2:0]key_reg;//中间变量,存放当前按键信号的寄存器类型的值,用于和下一次信号按键的值作对比

always @(posedge clk or negedge rst)
   begin
     if(rst==1'b0)
       begin
         delay_cnt <=20'd0;
         key_reg[0]   <=1'd1;    //初始化中间值  
         key_reg[1]   <=1'd1;    //初始化中间值  
         key_reg[2]   <=1'd1;    //初始化中间值           
       end
     else 
        begin
         key_reg[0] <= key[0];
         key_reg[1] <= key[1];
         key_reg[2] <= key[2];
          if((key_reg[0] !=key[0])||(key_reg[1] !=key[1])||(key_reg[2] !=key[2]) )//不等,此时有抖动
            delay_cnt <= delay;//开始倒计时,直到delay_cnt为零为止(开始进入延时消抖状态)
          else
            begin
              if(delay_cnt >20'd0)//如果延时延时寄存器大于0,说明延时未结束,继续倒计时
                delay_cnt<= delay_cnt -20'd1;
              else 
                delay_cnt<=20'd0;//如果延时计时器小于等于0,那么延时计时器归0,延时结束
            end
        end
   
   end
//根据延时寄存器获取key[0]状态及其稳定的信号
always @(posedge clk or negedge rst)
    begin
      if(rst==1'b0)
        begin
          flag[0] <= 1'b0;//抖动标志,初始化为0
          key_value[0]    <=1'b1;//记录稳定信号,初始化为1,高电平有效      
        end
      else if(delay_cnt == 20'd0)
        begin
        flag[0] <= 1'b1;//已经消抖,延时计时器完成了,改变消抖状态为1
          key_value[0] <= key[0];//key_value[0]保存key[0]的稳定信号,
        end
      else
        begin
          flag[0] <= 1'b0;//消抖未完成,延时计时器未结束,flag仍为0
          key_value[0] <= key_value[0];//消抖未完成,延时计时器未结束,key未进入稳定状态,key_value不计key的值,直到key稳定才计入
        end
    end
//根据延时寄存器获取key[1]状态及其稳定的信号
always @(posedge clk or negedge rst)
    begin
      if(rst==1'b0)
        begin
          flag[1] <= 1'b0;//抖动标志,初始化为0
          key_value[1]    <=1'b1;//记录稳定信号,初始化为1,高电平有效      
        end
      else if(delay_cnt == 20'd0)
        begin
        flag[1] <= 1'b1;//已经消抖,延时计时器完成了,改变消抖状态为1
          key_value[1] <= key[1];//key_value区key的稳定信号,
        end
      else
        begin
          flag[1] <= 1'b0;//消抖未完成,延时计时器未结束,flag仍为0
          key_value[1] <= key_value[1];//消抖未完成,延时计时器未结束,key未进入稳定状态,key_value不计key的值,直到key稳定才计入
        end
    end
//根据延时寄存器获取key[2]状态及其稳定的信号
always @(posedge clk or negedge rst)
    begin
      if(rst==1'b0)
        begin
          flag[2] <= 1'b0;//抖动标志,初始化为0
          key_value[2]    <=1'b1;//记录稳定信号,初始化为1,高电平有效      
        end
      else if(delay_cnt == 20'd0)
        begin
        flag[2] <= 1'b1;//已经消抖,延时计时器完成了,改变消抖状态为1
          key_value[2] <= key[2];//key_value区key的稳定信号,
        end
      else
        begin
          flag[2] <= 1'b0;//消抖未完成,延时计时器未结束,flag仍为0
          key_value[2] <= key_value[2];//消抖未完成,延时计时器未结束,key未进入稳定状态,key_value不计key的值,直到key稳定才计入
        end
    end
endmodule

小灯模块

module led
(
   input wire  clk,
   input wire  rst,
   input [2:0] flag,
   input [2:0] key_value,
   
   output reg [3:0]  led
);
reg [25:0] cnt;
parameter T=26'd50_000_000;
always @(posedge clk or negedge rst)
    begin
       if(rst==1'b0)
         cnt<= 26'd0;
       else if(cnt == T-26'd1)
         cnt <=26'd0;
       else 
         cnt <= cnt + 26'd1;
    
    end
//
always @(posedge clk or negedge rst)
    begin
      if(rst==1'b0)
        begin
          led <= 4'b1110;
        end
      else if(flag[0]==1'b1 &&key_value[0] == 1'b0)
         begin
          if(cnt== T-26'd1)
            led <= {led[2:0],led[3]}; 
         else 
            led<=led;
         end            
       else if(flag[1]==1'b1 &&key_value[1] == 1'b0)
         begin
           if(cnt== T-26'd1)
            led <= ~led; 
           else 
            led<=led;
         end
      else if(flag[2]==1'b1 &&key_value[2] == 1'b0)begin
            led <=4'b0101; 
          end
      else begin
             led <=4'b1110; 
      end          
    end




endmodule

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值