zoukankan      html  css  js  c++  java
  • 流水灯的按键方向控制

    module liushuideng
    (
    clk,rst_n,led_0,sw1_n,sw2_n,sw3_n
    );
    input clk; //时钟信号,50MHZ
    input rst_n; //复位信号,低电平有效
    input sw1_n,sw2_n,sw3_n; //三个独立按键,低表示按下
    output[3:0] led_0; //流水灯,0--灭,1--不灭
    //--------------------------------------------------------
    reg led_dir; //0--right,1--left
    reg led_on; //0--off,1--on

    reg[23:0] cnt;

    always @(posedge clk or negedge rst_n) //计数
    if(!rst_n)
    cnt <=24'd0;
    else
    cnt <= cnt+1'b1;

    reg[3:0] led_move;

    always @(posedge clk or negedge rst_n) //流水灯
    if(!rst_n)
    led_move <= 4'b1;
    else if(cnt == 24'hffffff && led_on)
    begin
    if(led_dir)
    led_move <= {led_move[2:0],led_move[3]}; //left
    else
    led_move <= {led_move[0],led_move[3:1]}; //right
    end

    //---------------------------------------------------------

    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}; //每个时钟周期都会把按键值赋给key_rst

    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_r

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

    //------------------------------------------------------

    reg[23:0] cnt_cn;//计数寄存器

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

    reg[2:0] low_sw;

    always @ (posedge clk or negedge rst_n)
    if (!rst_n)
    low_sw <= 3'b111;
    else if(cnt_cn == 24'hffffff) //满20ms,将按键值锁存到寄存器low_sw中
    low_sw <= {sw3_n,sw2_n,sw1_n}; //每个20ms执行一次

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

    always @ ( posedge clk or negedge rst_n )
    if (!rst_n)
    low_sw_r <= 3'b111;
    else
    low_sw_r <= low_sw; //每个时钟周期采一次

    /*
    low_sw 111 111 111 110 110 110
    ~low_sw 000 000 000 001 001 001
    low_sw_r 111 111 111 110 110 110

    led_ctr1 000 000 000 001 000 000
    */

    //当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期
    wire[2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
    begin
    led_on <= 1'b0;
    led_dir <= 1'b0;
    end
    else
    begin //某个按键值变化时,LED将做亮灭、左移或右移操作
    if ( led_ctrl[0] ) led_on <= ~led_on;
    if ( led_ctrl[1] ) led_dir <= 1'b1;
    if ( led_ctrl[2] ) led_dir <= 1'b0;
    end

    assign led_0 = led_dir; //LED

    endmodule

  • 相关阅读:
    第二章 搭建Android开发环境
    彻底修改 Windows 系统用户名
    第一章 Android系统移植与驱动开发概述
    返回一个整数数组中最大子数组的和。
    返回一个二维整数数组中最大子数组的和。
    返回一个整数数组中最大的子数组的和。
    四则运算
    关于南方Cass的使用感受
    数据结构-王道2017-第3章 栈和队列-栈和队列的应用
    数据结构-王道2017-第3章 栈和队列-队列
  • 原文地址:https://www.cnblogs.com/xinshuwei/p/5647840.html
Copyright © 2011-2022 走看看