主要功能:按下按键0,从左到右点亮led;按下按键1,从右到左点亮led;按下按键2时,四个led间隔亮灭;按下按键3时,点亮全部led。亮灭间隔时间为0.5s,时钟为50MHz.
//author :bronceyang
//time :2020年4月16日
//version: 1.0
//功能:实现按键控制led的亮灭
module key_led(
input sys_clk,
input sys_rst_n,
input [3:0]key,
output reg [3:0]led
);
//parameter define
parameter COUNTER_T=25'd25_000_000;
//reg define
reg [24:0]cnt_time;
reg [1:0]led_control;
//wire define
//*******************************************
// main()
//*******************************************
//产生0.5s的计数器
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
cnt_time<=25'd0;
else if (cnt_time<COUNTER_T)
cnt_time<=cnt_time+1'b1;
else
cnt_time<=25'd0;
end
//led 状态的选择
always @(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n)
led_control<=2'b00;
else if (cnt_time==COUNTER_T)
led_control<=led_control+1'b1;
else
led_control<=led_control;
end
//识别按键输入,输出相应的led状态
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
led<=4'b0000; //LED 高电平点亮,低电平熄灭
else if (key[0]==1'b0) //按键按下输出低电压
case(led_control)
2'b00:led<=4'b1000;
2'b01:led<=4'b0100;
2'b10:led<=4'b0010;
2'b11:led<=4'b0001;
default:led<=4'b0000;
endcase
else if (key[1]==1'b0)
case(led_control)
2'b00:led<=4'b0001;
2'b01:led<=4'b0010;
2'b10:led<=4'b0100;
2'b11:led<=4'b1000;
default:led<=4'b0000;
endcase
else if (key[2]==1'b0)
case(led_control)
2'b00:led<=4'b1111;
2'b01:led<=4'b0000;
2'b10:led<=4'b1111;
2'b11:led<=4'b0000;
default:led<=4'b0000;
endcase
else if (key[3]==1'b0)
led<=4'b1111;
else
led<=4'b0000;
end
endmodule
testbench:
`timescale 1 ns/ 1 ns
module key_led_tb();
parameter T = 20;
reg [3:0] key ;
reg sys_clk ;
reg sys_rst_n;
reg key_value;
wire [3:0] led;
initial begin
key <=4'b1111;//按键初始状态为全断开
sys_clk <=1'b0; //初始时钟为低电平
sys_rst_n <=1'b0; //复位信号初始为低电平
#T sys_rst_n <=1'b1; //一个时钟周期后复位信号拉高
#600_000_020 key[0] <=0; //0.6s时按下按键1
#2000_000_000 key[0] <=1;
key[1] <=0; //2s后松开按键1,按下按键2
#2000_000_000 key[1] <=1;
key[2] <=0; //2s后松开按键2,按下按键3
#2000_000_000 key[2] <=1;
key[3] <=0; //2s后松开按键3,按下按键4
#2000_000_000 key[3] <=1; //2s后松开按键4
end
仿真分析: