打印
[FPGA]

关于按键消抖的问题。

[复制链接]
889|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
28182900|  楼主 | 2016-8-14 18:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ST, RS, ge, edge, POS
reg[2:0] key_rst;

always @(posedge clk  or negedge rst_n)
    if (!rst_n) key_rst <= 3'b111;
    else key_rst <= {sw3_n,sw2_n,sw1_n};

reg[2:0] key_rst_r;       //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中

always @( posedge clk  or negedge rst_n)
    if (!rst_n) key_rst_r <= 3'b111;
    else key_rst_r <= key_rst;
   
//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire[2:0] key_an = key_rst_r & ( ~key_rst);

由于相差一个时钟周期最终key_an变为1,但是两个always之间是并行的啊,怎么会相差一个时钟周期呢?

相关帖子

沙发
28182900|  楼主 | 2016-8-14 20:58 | 只看该作者
module johnson(
                        clk,rst_n,
                        key1,key2,key3,
                        led0,led1,led2,led3
                );

input clk;                //主时钟,50MHz
input rst_n;        //低电平复位
input key1,key2,key3;                        // 按键接口
output led0,led1,led2,led3;                // LED等接口

//------------------------------------
reg[23:0] delay;        //延时计数器

always @ (posedge clk or negedge rst_n)
        if(!rst_n) delay <= 0;
        else delay <= delay+1;        //不断计数,周期为320ms

reg[2:0] key_value;                //键值寄存器

always @ (posedge clk or negedge rst_n)
        if(!rst_n) key_value <= 3'b111;       
        else if(delay == 24'hffffff) key_value <= {key3,key2,key1};        //delay 320ms,锁定键值

//-------------------------------------
reg[2:0] key_value_r;

always @ (posedge clk or negedge rst_n)
        if(!rst_n) key_value_r <= 3'b111;
        else key_value_r <= key_value;

wire[2:0] key_change;        //判定前后20ms的键值是否发生了改变,若是,则key_change置高

assign key_change = key_value_r & (~key_value);        //check key_value negedge per clk
//------------------------------------
reg stop_start,left_right;        //流水灯控制位

always @ (posedge clk or negedge rst_n)
        if(!rst_n) begin
                stop_start <= 1;
                left_right <= 1;
                end
        else
                if(key_change[2]) stop_start <= ~stop_start;        //开始结束控制位
                else if(key_change[1]) left_right <= 1;                        //流水灯方向控制
                else if(key_change[0]) left_right <= 0;                        //流水灯方向控制

//-------------------------------------
reg[3:0] led_value_r;        // LED值寄存器

always @ (posedge clk or negedge rst_n)
        if(!rst_n) led_value_r <= 4'b1110;
        else if(delay == 24'h3fffff && stop_start)        //流水灯控制
                case (left_right)        //方向控制
                        1: led_value_r <= {led_value_r[2:0],led_value_r[3]};        //右移
                    0: led_value_r <= {led_value_r[0],led_value_r[3:1]};        //左移
                        default: ;
                        endcase

assign {led3,led2,led1,led0} = ~led_value_r;

endmodule

使用特权

评论回复
板凳
297229936| | 2016-8-15 10:57 | 只看该作者
学习了!!

使用特权

评论回复
地板
28182900|  楼主 | 2016-8-15 20:51 | 只看该作者
module led_seg7(
                        clk,rst_n,
                        sm_cs1_n,sm_cs2_n,sm_db       
                );

input clk;                // 50MHz
input rst_n;        // 复位信号,低有效

output sm_cs1_n,sm_cs2_n;        //数码管片选信号,低有效
output[6:0] sm_db;        //7段数码管(不包括小数点)

reg[24:0] cnt;        //计数器,最大可以计数到2的25次方*20ns=640ms

always @ (posedge clk or negedge rst_n)
        if(!rst_n) cnt <= 25'd0;
        else cnt <= cnt+1'b1;        //循环计数
       
reg[3:0] num;        //显示数值

always @ (posedge clk or negedge rst_n)
        if(!rst_n) num <= 4'd0;
        else if(cnt == 24'hffffff) num <= num+1'b1;        //每640ms增一

//-------------------------------------------------------------------------------
/*        共阴极 :不带小数点
              ;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,
                        sega        = 7'h77,
                        segb        = 7'h7c,
                        segc        = 7'h39,
                        segd        = 7'h5e,
                        sege        = 7'h79,
                        segf        = 7'h71;

reg[6:0] sm_dbr;                //7段数码管(不包括小数点)
       
always @ (num)
                case (num)        //NUM值显示在两个数码管上
                        4'h0: sm_dbr <= seg0;

                        4'h1: sm_dbr <= seg1;
                        4'h2: sm_dbr <= seg2;
                        4'h3: sm_dbr <= seg3;
                        4'h4: sm_dbr <= seg4;
                        4'h5: sm_dbr <= seg5;
                        4'h6: sm_dbr <= seg6;
                        4'h7: sm_dbr <= seg7;
                        4'h8: sm_dbr <= seg8;
                        4'h9: sm_dbr <= seg9;
                        4'ha: sm_dbr <= sega;
                        4'hb: sm_dbr <= segb;
                        4'hc: sm_dbr <= segc;
                        4'hd: sm_dbr <= segd;
                        4'he: sm_dbr <= sege;
                        4'hf: sm_dbr <= segf;
                        default: ;
                        endcase

assign sm_db = sm_dbr;
assign sm_cs1_n = 1'b0;                //数码管1常开
assign sm_cs2_n = 1'b0;                //数码管2常开

endmodule

使用特权

评论回复
5
28182900|  楼主 | 2016-8-15 21:18 | 只看该作者
本帖最后由 28182900 于 2016-8-18 17:15 编辑

module mux16(
                        clk,rst_n,
                        start,ain,bin,yout,done
                );
               
        input clk;                //芯片的时钟信号。
        input rst_n;        //低电平复位、清零信号。定义为0表示芯片复位;定义为1表示复位信号无效。
        input start;         //芯片使能信号。定义为0表示信号无效;定义为1表示芯片读入输入管脚得乘数和被乘数,并将乘积复位清零。
        input[15:0] ain;        //输入a(被乘数),其数据位宽为16bit.
        input[15:0] bin;        //输入b(乘数),其数据位宽为16bit.
        output[31:0] yout;        //乘积输出,其数据位宽为32bit.
        output done;                //芯片输出标志信号。定义为1表示乘法运算完成.

        reg[15:0] areg;        //乘数a寄存器
        reg[15:0] breg;        //乘数b寄存器
        reg[31:0] yout_r;        //乘积寄存器
        reg done_r;
        reg[4:0] i;                //移位次数寄存器

        always@(posedge clk)
        begin
                if(!rst_n) begin
                                areg <= 16'h0000;
                                breg <= 16'h0000;
                                done_r <= 1'b0;
                                yout_r <= 32'h00000000;
                                i <= 5'd0;
                        end
                else if(start)                //启动运算
                        begin
                        
                                if(i < 5'd21) i <= i+1'b1;
                                if(i == 5'd0) begin        //锁存乘数、被乘数
                                                areg <= ain;
                                                breg <= bin;
                                        end
                                else if(i > 5'd0 && i < 5'd16) begin
                                                        if(areg[i-1]) yout_r = {1'b0,yout[30:15]+breg,yout_r[14:1]};        //累加并移位
                                                        else yout_r <= yout_r>>1;        //移位不累加
                                                end
                                else if(i == 5'd16 && areg[15]) yout_r[31:16] <= yout_r[31:16]+breg;        //累加不移位
                                else if(i == 5'd18) done_r <= 1'b1;        //乘完成标志位置位
                                else if(i == 5'd20) done_r <= 1'b0;         //乘完成标志位清除
                        end
                 else i <= 5'd0;
        end
        
        assign done = done_r;
        assign yout = yout_r;

endmodule 乘法器设计实验.pdf (112.93 KB)

ain:0000000001011001 89
bin:0000000000100001 33
yout_r = {1b0,yout[30:15]+breg,yout_r[14:1]};
        
00084000:00000000000010000100000000000000
00042000:00000000000001000010000000000000
00021000:00000000000000100001000000000000
00094800:00000000000010010100100000000000
000ce400:00000000000011001110010000000000
00067200:00000000000001100111001000000000
000b7900:00000000000010110111100100000000
0005bc80:00000000000001011011110010000000
0002de40:00000000000000101101111001000000
00016f20:00000000000000010110111100100000
0000b790:00000000000000001011011110010000
00005bc8:00000000000000000101101111001000
00002de4:00000000000000000010110111100100
000016f2:00000000000000000001011011110010
00000b79:00000000000000000000101101111001


mux16.rar

836.04 KB

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

1127

帖子

2

粉丝