FPGA实战3-3:按键控制LED设置与实现

流程

复位键:点亮最右边灯[3:0],即第0位
按键:LED依次往左移动
SW:按键,按下为1,抬起为0

消除抖动代码

/*按键消抖模块*/
module debounce(
input wire clk	,
input wire rst_n	,
input wire sw	,

output reg key
);
//50Mhz--0.02us     50个周期,1us;50*10000=10ms
//10ms500000个时钟周期,转为二进制是1111010000100100000,一共19位
reg[18:0]	cnt_10ms;
parameter CNT_10MS = 30;        //30仿真
reg		flag;

//cnt_10ms  sw按键:按下低电平;抬起高电平
always @(posedge clk or negedge rst_n)
if(rst_n == 0)
    cnt_10ms <= 0;
else if((cnt_10ms==CNT_10MS+1)&&(sw==1))//CNT_10MS为499999
    cnt_10ms<=CNT_10MS+1;
    else if(sw==1)
        cnt_10ms<=cnt_10ms+1;
        else if(sw == 0)
            cnt_10ms<=0;

//flag
always @(posedge clk or negedge rst_n)
if(rst_n == 0)
    flag <= 0;
else if((cnt_10ms==CNT_10MS) &&(sw==1))
    flag<=1;
    else 
        flag <=0;

//key
always @(posedge clk or negedge rst_n)
if(rst_n == 0)
    key <=0;
else if(flag == 1)
    key <= 1;
    else
    key <=0;
endmodule 

LED模块

//再写led灯子模块
/*led灯模块*/
module led(
input wire clk	,
input wire rst_n	,
input wire key	,

output reg[3:0] led
);

//led
always@(posedge clk or negedge rst_n)
if(rst_n == 0)
    led <= 4'b0001;
else if(key == 1)       //往左移动流水
    led <= {led[2:0],led[3]};
endmodule
//将两个子模块在顶层模块中例化并连线。

顶层模块


/*顶层模块*/
module top(
input 	wire	clk	,
input	wire	rst_n,
input 	wire	sw	,
output 	wire[3:0]	led
);
wire key;
debounce debounce_inst(
                    .clk(clk),
                    .rst_n(rst_n),
                    .sw(sw),
                    .key(key)
                    );
led led_inst(
        .clk(clk),
        .rst_n(rst_n),
        .key(key),
        .led(led)
        );
endmodule

测试代码:


`timescale 1ns / 1ps
module tb();
reg 	clk;					//因为clk要进行赋值变化,所以为reg类型。
reg 	rst_n;				//和clk同理
reg		sw;
reg[8:0]	time1;
wire[3:0] led;				//此处要检测led的信号,所以设置为wire类型
initial						//初始化开始
	begin				
		clk=0;			//首先设置clk为0
		rst_n<=0;			//rst_n为0
		sw<=0;            //没按下,为0
		time1<=0;
		#100				//延时100ns,为了便于查看波形,通常会进行一段时间		
		rst_n<=1;			//复位按键置1
	end
always #10 clk=~clk;			//每过10ns后,clk取反,这里clk时钟周期为20ns,50Mhz

//time1
always #20          // 21-70按下
	if(time1 == 200)
		time1 <= 0;
	else
		time1 <= time1 +1;
//sw		
always #20
	if((time1 < 20)||(time1>70&&time1<100))
		sw <= {$random};
	else if(time1 > 100)
		sw <= 0;
	else           //按下为1
		sw <=1;		
		
top top_inst(				//将模块例化,并连线
            .clk	(clk),
            .rst_n (rst_n),
            .sw	(sw),
            .led	(led)
            );
endmodule

功能仿真图放大图形

在这里插入图片描述
990-380=610ns>20*30=600ns
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值