FPGA——zhixin培训 Day_08——边沿检测

一、设计背景:

边沿检测电路:如上图,为我们待检测信号,可以看出边沿的特性:边沿两侧信号的电平发生了变化。红色为上升沿,绿色为下降沿。上升沿之前电平为低,上升沿之后电平为高。下降沿之前为电平为高,下降沿之后电平为低。

二、设计需求:

设计边沿检测电路,可检测上升沿和下降沿。

三、设计方案:

实序图:

五、代码

module check_edge(clk,rst_n,signal,pos_edge,neg_edge);

 

input clk;

input rst_n;

input signal;

 

output pos_edge;

output neg_edge;

 

reg buffer1;

reg buffer2;

 

always @(posedge clk or negedge rst_n)

    begin

        if(!rst_n)

           begin

               buffer1 <= 1'b0;

           end

        else

           begin

               buffer1 <= signal;

           end

    end

 

always @(posedge clk or negedge rst_n)

    begin

        if(!rst_n)

           begin

               buffer2 <= 1'b0;

           end

        else

           begin

               buffer2 <= buffer1;

           end

    end

   

    assign pos_edge = buffer1 && (!buffer2);//上升沿

    assign neg_edge = buffer2 && (!buffer1);//下降沿

    endmodule

六、仿真验证:

如下

`timescale 1ns/1ns

 

module tb_check_edge();

 

reg clk;

reg rst_n;

reg signal;

 

wire pos_edge;

wire neg_edge;

 

check_edge check_edge_inst(

    .clk(clk),

    .rst_n(rst_n),

    .signal(signal),

    .pos_edge(pos_edge),

    .neg_edge(neg_edge)

);

 

initial

    begin

        clk = 1;

        rst_n = 0;

        signal = 0;

       #100

        rst_n = 1;

        #100

        signal = 1;

        #100

        signal = 0;

        #100

        signal = 1;

        #200

        signal = 0;

        #2000

        $stop;

    end 

    always #10 clk = ~clk;

    endmodule

练习:

利用按键消抖和边沿检测,实现按键按下(检测下降沿),完成LED点亮,抬起(检测上升沿),LED灯点亮(第二个)。要求:1设计架构;2设计方案;3仿真测试4下板验证。

1、框架图:

2、代码实现:

顶层代码:

//顶层

module key_edge_led(clk,rst_n,key_in,led);

 

       input clk;

       input rst_n;

       input key_in;

      

       output [1:0]led;

      

       wire flag;

       wire pos_edge;

       wire neg_edge;

       /*#(.cnt_num(4)) */

       //#(.cnt_num(4))

       filter  /*#(.cnt_num(4)) */ filter_inst(

              .clk(clk),

              .rst_n(rst_n),

              .key_in(key_in),

              .neg(neg)

       );

      

       check_edge check_edge_inst(

              .clk(clk),

              .rst_n(rst_n),

              .signal(neg),

              .pos_edge(pos_edge),

              .neg_edge(neg_edge)

       );

      

       key_led key_led_inst(

              .pedge(pos_edge),

              .nedge(neg_edge),

              .rst_n(rst_n),

              .clk(clk),

              .led(led)

       );

 

endmodule 

按键消抖模块:

       //按键消抖模块:利用尖峰脉冲信号来对按键的动作中作一次处理

module filter(clk,rst_n,key_in,neg);

 

       input clk;

       input rst_n;

       input key_in;

      

       output reg neg;//输出的尖峰脉冲信号(按键稳定的标志信号)

 

       reg[31:0] cnt;

       reg state;//状态寄存器:两个状态(按下和抬起)

       reg flag;

      

       `define s0 1'b0

       `define s1 1'b1

             

       parameter cnt_num = 50_000_000/100-1;

      

       always @(posedge clk or negedge rst_n)

              begin

                     if(!rst_n)

                            begin

                                   cnt <= 32'b0;

                                   state <= `s0;

                                   flag <= 1'b0;

                            end

                     else

                            begin

                                   case(state)

                                          `s0:begin

                                                               if(!key_in )//有按键按下

                                                                      begin

                                                                             if(cnt < cnt_num)//未达到消抖时间

                                                                                    begin

                                                                                           cnt <= cnt + 1'b1;

                                                                                           flag <= 1'b0;

                                                                                    end

                                                                             else//达到消抖时间

                                                                                    begin

                                                                                           cnt <= 32'b0;

                                                                                           flag <= 1'b1;

                                                                                           state <= `s1;

                                                                                    end

                                                                      end

                                                               else //没有按键按下

                                                                      begin

                                                                             state <= `s0;//等待按键按下

                                                                             cnt <= 32'b0;

                                                                             flag <= 1'b0;

                                                                      end

                                                  end

                                          `s1:begin

                                                                      flag <= 1'b0;

                                                                      if(key_in)//按键抬起

                                                                             begin

                                                                                    if(cnt < cnt_num)//没有到消抖时间

                                                                                           begin

                                                                                                  cnt <= cnt + 1'b1;

                                                                                                  flag <= 1'b0;

                                                                                           end

                                                                                    else//到达消抖时间

                                                                                           begin

                                                                                                  cnt <= 32'd0;

                                                                                                  flag <= 1'b1;

                                                                                                  state <= `s0;

                                                                                           end

                                                                             end

                                                                      else//按键未抬起

                                                                             begin

                                                                                    state <= `s1;//等待按键抬起

                                                                             end

                                                   end    

                                          default : state <= `s0;

                                   endcase

                            end

              end

             

              always @(posedge clk or negedge rst_n)

              begin

                     if(!rst_n)

                            begin

                                   neg <= 1'b1;

                            end

                     else

                            begin

                                   if((flag == 1) &&  (key_in == 1))

                                          begin

                                                 neg <= 1'b1;

                                          end

                                   else if((flag == 1) &&  (key_in == 0))

                                          begin

                                                 neg <= 1'b0;

                                          end

                            end

              end 

endmodule

边沿检测:

       module check_edge(clk,rst_n,signal,pos_edge,neg_edge);

 

       input clk;

       input rst_n;

       input signal;

      

       output pos_edge;

       output neg_edge;

      

       reg buffer1;

       reg buffer2;

      

       always @(posedge clk or negedge rst_n)

              begin

                     if(!rst_n)

                            begin

                                   buffer1 <= 1'b0;

                            end

                     else

                            begin

                                   buffer1 <= signal;

                            end

              end

 

       always @(posedge clk or negedge rst_n)

              begin

                     if(!rst_n)

                            begin

                                   buffer2 <= 1'b0;

                            end

                     else

                            begin

                                   buffer2 <= buffer1;

                            end

              end

             

              assign pos_edge = buffer1 && (!buffer2);//上升沿

              assign neg_edge = buffer2 && (!buffer1);//下降沿

endmodule

LED显示:

       module key_led(clk,rst_n,pedge,nedge,led);

 

       input pedge;

       input nedge;

       input rst_n;

       input clk;

      

       output reg [1:0]led;

      

       always @(posedge clk or negedge rst_n)

              begin

                     if(!rst_n)

                            led <= 2'b00;

                     else

                            begin

                                   if(nedge)

                                          led <= 2'b10;

                                   else if(pedge)

                                          led <= 2'b01;

                            end

              end

             

endmodule

3、仿真验证

下板与仿真相符。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值