按键控制流水灯

顶层模块


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

//wire FLAG;
wire 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 key,
   //output reg flag,//判断
   output reg key_value //消抖后的key

);
parameter delay=20'd1_000_000;//10ms
reg [19:0] delay_cnt;//延时计数器
reg key_reg;//中间变量,存放当前按键信号的寄存器类型的值,用于和下一次信号按键的值作对比

always @(posedge clk or negedge rst)
   begin
     if(rst==1'b0)
       begin
         delay_cnt <=20'd0;
         key_reg   <=1'd1;    //初始化中间值   
       end
     else 
        begin
         key_reg <= key;
          if(key_reg !=key)//不等,此时有抖动
            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状态及其稳定的信号
always @(posedge clk or negedge rst)
    begin
      if(rst==1'b0)
        begin
        //  flag <= 1'b0;//抖动标志,初始化为0
          key_value    <=1'b1;//记录稳定信号,初始化为1,高电平有效      
        end
      else if(delay_cnt == 20'd1)
        begin
        // flag <= 1'b1;//已经消抖,延时计时器完成了,改变消抖状态为1
          key_value <= key;//key_value区key的稳定信号,
        end
      else
        begin
         // flag <= 1'b0;//消抖未完成,延时计时器未结束,flag仍为0
          key_value <= key_value;//消抖未完成,延时计时器未结束,key未进入稳定状态,key_value不计key的值,直到key稳定才计入
        end
    end
endmodule

小灯模块


module led
(
   input wire  clk,
   input wire  rst,
   //input flag,
   input 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(key_value == 1'b0)
      else 
        begin
         if(/* flag==1'b1 && */ (key_value==1'b0)&&(cnt == T-26'd1))  //已经消抖,且key信号稳定
            //led <= ~led;
            led <= {led[2:0],led[3]};
         else 
           //led <= 1'b1;
            
            led<=led;
        end        
    end


endmodule

上面小灯模块实现的为当按键按下,小灯现实右移

下面小灯模块是实现按键每按下一次,小灯向右移动一次,其中flag未注释,所以上面的顶层模块和按键消抖模块,都需要取消flag的注释


module led
(
   input wire  clk,
   input wire  rst,
   input flag,
   input 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==1'b1 &&key_value == 1'b0)
        
      /* else 
        begin
         if(/* flag==1'b1 &&  (key_value==1'b0)&&(cnt == T-26'd1))  //已经消抖,且key信号稳定
            //led <= ~led;*/
            led <= {led[2:0],led[3]}; 
         else 
           //led <= 1'b1;
            
            led<=led;
        //end        
    end


endmodule

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值