文章目录
- 一、实验环境
- 二、实验任务
- 三、系统设计
- 四、实验过程
- 4.1 编写verilog代码
- 4.2 引脚配置
- 五、仿真
- 5.1 仿真代码
- 5.2 仿真结果
- 六、实验结果
- 七、总结
一、实验环境
quartus 18.1
modelsim
vscode
Cyclone IV开发板
二、实验任务
使用开发板上的四个按键控制四个LED灯。按下不同的按键时,四个LED灯显示不同效果。
三、系统设计
四个按键外加时钟和复位信号作为输入,两个计数器模块分别用于0.2s时间的计数和状态的计数。led模式选择模块根据状态计数器的改变,来改变四个led的状态,形成不同的样式。
四、实验过程
4.1 编写verilog代码
module key_led(
input clk ,//时钟50MHz
input rst_n,//复位信号,下降沿有效negtive
input [3:0] key ,//四个按键
output reg [3:0] led //四个led灯
);
parameter TIME = 24'd10_000_000;//0.2S
reg [23:0] cnt ;//计数器0.2S
reg [1:0] state;//记录四个led状态
//0.2s计数器模块
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin//复位
cnt <= 24'd0;//计数器清0
end
else if(cnt == TIME - 1)begin//记满10_000_000,0~9_999_999
cnt <= 24'd0;//计数器清0
end
else begin
cnt <= cnt + 1'd1;//其他情况下计数器加1
end
end
//状态计数模块
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin//复位信号
state <= 2'd0;//状态清0
end
else if(cnt == TIME - 1)begin//记满10_000_000,0~9_999_999 0.2s
state <= state + 2'd1;//状态加1
end
else begin
state <= state;//其他情况状态保持不变
end
end
//状态控制led模块
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin//复位信号
led <= 4'b0000;//led全灭
end
else if(key[0] == 0)begin//右边第1个按键按下,按键低电平0有效
case(state)//判断状态的值
2'd0: led <= 4'b0001;//右边第1个led灯亮
2'd1: led <= 4'b0010;//右边第2个led灯亮
2'd2: led <= 4'b0100;//右边第3个led灯亮
2'd3: led <= 4'b1000;//右边第4个led灯亮
default:;//默认情况不能忘,可以不写,但是要把stat情况考虑完
endcase
end
else if(key[1] == 0)begin//右边第2个按键按下,按键低电平0有效
case(state)//判断状态的值
2'd0: led <= 4'b1000;//左边第1个led灯亮
2'd1: led <= 4'b0100;//左边第2个led灯亮
2'd2: led <= 4'b0010;//左边第3个led灯亮
2'd3: led <= 4'b0001;//左边第4个led灯亮
default:;
endcase
end
else if(key[2] == 0)begin//右边第3个按键按下,按键低电平0有效
case(state)
2'd0: led <= 4'b1111;//全亮
2'd1: led <= 4'b0000;//全灭
2'd2: led <= 4'b1111;//全亮
2'd3: led <= 4'b0000;//全灭
default:;
endcase
end
else if(key[3] == 0)begin//右边第4个按键按下,按键低电平0有效
case(state)
2'd0: led <= 4'b1111;//全亮
2'd1: led <= 4'b1111;//全亮
2'd2: led <= 4'b1111;//全亮
2'd3: led <= 4'b1111;//全亮
default:;
endcase
end
else begin
led <= 4'b0000;//其他情况默认4个led灯全灭
end
end
endmodule
4.2 引脚配置
五、仿真
5.1 仿真代码
`timescale 1ns/1ns//单位/精度
module key_led_tb();
reg clk ;//时钟信号
reg rst_n;//复位信号
reg [3:0] key ;//按键信号
wire [3:0] led ;//led灯信号
parameter TIME = 10;//间隔时间,由10_000_000变为10,便于仿真观察
parameter CYCLE = 20;//周期20ns
always #(CYCLE/2) clk = ~clk;//每10ns翻转一次,刚好模拟时钟周期50MHz
initial begin
clk = 1'b0;//初始时钟为低电平
rst_n = 1'b0;//复位信号置0,下降沿有效,初始化
#(CYCLE);//时钟20ns
rst_n = 1'b1;//复位信号置1
#(CYCLE * TIME * 4);//4个led灯,4个间隔,所以乘以4
key = 4'b1110;//按下右边第1个按键
#(CYCLE * TIME * 4);
key = 4'b1101;//按下右边第2个按键
#(CYCLE * TIME * 4);
key = 4'b1011;//按下右边第3个按键
#(CYCLE * TIME * 4);
key = 4'b0111;//按下右边第4个按键
#(CYCLE * TIME * 4);
$stop;//停止
end
//实例化模块
key_led #(.TIME (TIME)) u_key_led
(
.clk (clk) ,//时钟50MHz
.rst_n (rst_n),//复位信号,下降沿有效
.key (key) ,//按键信号
.led (led)//led灯
);
endmodule
5.2 仿真结果
六、实验结果
七、总结
本次实验除了使用了计数的寄存器,还引入了状态寄存器,使得逻辑结构更加清晰直观,但是本次实验中我们没有进行按键消抖,因此必须把按键按住不放才能实现led灯对应的状态。