找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3367|回复: 1
收起左侧

fpga基于环扭型计数器的流水灯实验-楠妹

[复制链接]
ID:77367 发表于 2015-4-19 01:32 | 显示全部楼层 |阅读模式
module johnson(
        clk,
        rst_n,
        key_1,
        key_2,
        key_3,
        key_4,
        led
        );
       
input clk;
input rst_n;
input key_1;
input key_2;
input key_3;
input key_4;
output reg [7:0] led;

//------------------------------------------------------------------------
//        按键检测
reg [3:0] key_r_1;                          //        锁存按键输入信号4拍
reg [3:0] key_r_2;
reg [3:0] key_r_3;
reg [3:0] key_r_4;

always @ (posedge clk or negedge rst_n)
        if(!rst_n)
                begin
                key_r_1 <= 4'b1111;
                key_r_2 <= 4'b1111;
                key_r_3 <= 4'b1111;
                key_r_4 <= 4'b1111;
                end
        else
                begin
                key_r_1 <= {key_r_1[2:0],key_1};
                key_r_2 <= {key_r_2[2:0],key_2};
                key_r_3 <= {key_r_3[2:0],key_3};
                key_r_4 <= {key_r_4[2:0],key_4};
                end

wire key_pos_1 = key_r_1[2] & ~key_r_1[3];  //        产生按键上升沿和下降沿标志位
wire key_neg_1 = ~key_r_1[2] & key_r_1[3];
wire key_pos_2 = key_r_2[2] & ~key_r_2[3];
wire key_neg_2 = ~key_r_2[2] & key_r_2[3];
wire key_pos_3 = key_r_3[2] & ~key_r_3[3];
wire key_neg_3 = ~key_r_3[2] & key_r_3[3];
wire key_pos_4 = key_r_4[2] & ~key_r_4[3];
wire key_neg_4 = ~key_r_4[2] & key_r_4[3];

//------------------------------------------------------------------------
//        19位计数器,用于计时20ms消抖
reg [19:0] cnt;

always @ (posedge clk or negedge rst_n)
        if(!rst_n)
                cnt <= 20'd0;
        else if((key_pos_1 || key_neg_1) || (key_pos_2 || key_neg_2) || (key_pos_3 || key_neg_3) || (key_pos_4 || key_neg_4))
                cnt <= 20'd0;
        else if(cnt<20'd999_999)
                cnt <= cnt + 1'b1;
        else
                cnt <= 20'd0;

reg [1:0] key_value_1;
reg [1:0] key_value_2;
reg [1:0] key_value_3;
reg [1:0] key_value_4;

always @ (posedge clk or negedge rst_n)
        if(!rst_n)
                begin
                key_value_1[0] <= 1'b1;
                key_value_2[0] <= 1'b1;
                key_value_3[0] <= 1'b1;
                key_value_4[0] <= 1'b1;
                end
        else if(cnt == 20'd999_999)
                begin
                key_value_1[0] <= key_r_1[3];
                key_value_2[0] <= key_r_2[3];
                key_value_3[0] <= key_r_3[3];
                key_value_4[0] <= key_r_4[3];
                end
       
always @ (posedge clk or negedge rst_n)
        if(!rst_n)
                begin
                key_value_1[1] <= 1'b1;
                key_value_2[1] <= 1'b1;
                key_value_3[1] <= 1'b1;
                key_value_4[1] <= 1'b1;
                end
        else if(cnt == 20'd999_999)
                begin
                key_value_1[1] <= key_value_1[0];
                key_value_2[1] <= key_value_2[0];
                key_value_3[1] <= key_value_3[0];
                key_value_4[1] <= key_value_4[0];
                end
               
wire led_star = ~key_value_1[0] & key_value_1[1];
wire led_stop = ~key_value_2[0] & key_value_2[1];       
wire led_lfsh = ~key_value_3[0] & key_value_3[1];
wire led_rgsh = ~key_value_4[0] & key_value_4[1];
       
//------------------------------------------------------------------------
//        左移,右移控制
reg led_en;
reg led_dir;

always @ (posedge clk or negedge rst_n)
        if(!rst_n)
                begin
                led_en <= 1'b0;
                led_dir <= 1'b0;
                end
        else if(led_star)
                led_en <= 1'b1;
        else if(led_stop)
                led_en <= 1'b0;
        else if(led_lfsh)
                led_dir <= 1'b0;
        else if(led_rgsh)
                led_dir <= 1'b1;

//------------------------------------------------------------------------
//        延时
reg [23:0] delay;
always @ (posedge clk or negedge rst_n)
        if(!rst_n)
                delay <= 24'd0;
        else
                delay <= delay + 1'b1;
               
//------------------------------------------------------------------------

always @ (posedge clk or negedge rst_n)
        if(!rst_n)
                led <= 8'b00000001;
        else if((delay == 24'h3fffff)&&(led_en))
                begin
                        case(led_dir)
                                1'b0 : led <= {led[6:0],led[7]};    //        左移
                                1'b1 : led <= {led[0],led[7:1]};                //        右移
                                default: ;
                        endcase
                end
        else ;
       
endmodule





回复

使用道具 举报

ID:69240 发表于 2015-5-22 11:24 | 显示全部楼层
刚开始学FPGA,不会流水灯,学习一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表