一、要求
两个按键KEY0、KEY1控制LED0、LED1的闪烁。
功能定义:
无按键按下:两个LED全亮;
按下KEY0:交替闪烁
按下KEY1:同时闪烁
二、实现
1.原理
把电路分成三个部分:计数器、控制器、LED灯
50MHZ时钟的周期为20ns,每0.5秒改变一次LED的状态,闪烁一次(两个状态)需要1秒,0.5秒需要2500_0000个时钟周期,2500_0000需要25位二进制数表示。
通过计数器来实现,定义一个25位的计数器cnt[24:0],每个clk上升沿计数一次。
同时定义控制信号led_ctrl,用于控制LED灯。当计数器完成一轮计数,将led_ctrl取反,完成第二轮计数时,再将led_ctrl取反,以此类推,那么led_ctrl每变化一次,灯会变更一次状态。
考虑计数器,当:
cnt < 2500_0000时,有cnt = cnt + 1;
cnt ≥ 2500_0000时,有cnt = 0,led_ctrl取反,进行下一轮计数。
考虑控制信号,当:
KEY = 10(即按下LED0)时,LED应该交替闪烁,闪烁周期为led_ctrl的周期,令:
led_ctrl = 0时,led = 01;
led_ctrl = 1时,led = 10;
KEY = 01(即按下LED1)时,LED应该同时闪烁,令:
led_ctrl = 0时,led = 11;
led_ctrl = 1时,led = 00;
2.代码
/*
-----------------------
功能定义:
无按键按下:两个LED全亮;
按下KEY0:交替闪烁
按下KEY1:同时闪烁
-----------------------
输入:时钟、复位、KEY0、KEY1
输出:LED0、LED1
-----------------------
为便于仿真,将计数周期调整为25
-----------------------
*/
module key_led(
input sys_clk,
input sys_rst_n,
input [1:0] key, //[key1,key0],按下为低电平
output reg [1:0] led //亮起为高电平
);
reg [24:0] cnt; //2500_0000需要25位表示
reg led_ctrl;
/*计数器*/
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt <= 25'd0;
else if(cnt < 25/*2500_0000*/)
cnt <= cnt + 1'b1;
else
cnt <= 25'd0;
end
/*控制信号*/
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
led_ctrl <= 1'b0;
else if(cnt == 25/*2500_0000*/)
led_ctrl = ~led_ctrl;
end
/*按键和led_ctrl对LED闪烁的控制*/
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
led <= 2'b11;
else case(key)
2'b10:
if(led_ctrl == 1'b0)
led <= 2'b01;
else
led <= 2'b10;
2'b01:
if(led_ctrl == 1'b0)
led <= 2'b11;
else
led <= 2'b00;
2'b11:
led <= 2'b11;
default: /*led <= 2'b11*/;
endcase
end
endmodule
testbench:
`timescale 1ns / 1ps
module tb_key_led();
reg sys_clk;
reg sys_rst_n;
reg [1:0] key;
wire [1:0] led;
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
key = 2'b11;
#60 sys_rst_n = 1'b1;
#40 key = 2'b10;//按下KEY0: 交替闪烁
#2000 key = 2'b11;//无按键按下: 两个灯全亮
#100 key = 2'b01;//按下KEY1: 同时闪烁
#2000 key = 2'b11;//无按键按下: 两个灯全亮
end
always #10 sys_clk = ~sys_clk; //5mhz时钟 0.05*1000 = 50MHZ
key_led u_key_led(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.key(key),
.led(led)
);
endmodule
3.仿真
可见在按下KEY0时,LED实现交替闪烁;按下KEY1时,LED实现同时闪烁;同时按下两个键时,LED全亮。
我好菜啊好菜好菜,菜到抠脚。
md一定要好好学习。
2022/1/18 17:03