文章目录
- 一、实验环境
- 二、实验任务
- 三、实验过程
- 3.1 verilog代码
- 3.2 引脚配置
- 四、仿真
- 4.1 仿真代码
- 4.2 仿真结果
- 五、实验结果
- 六、总结
一、实验环境
quartus 18.1
modelsim
vscode
Cyclone IV开发板
二、实验任务
呼吸灯是指灯光在微电脑的控制之下完成由亮到暗的逐渐变化,感觉好像是人在呼吸。本次实验是使用开发板上的四个led灯实现1s间隔的呼吸灯。使4个led灯由暗到亮,再由亮到暗的过程。
三、实验过程
3.1 verilog代码
module pwm_led (
input clk ,
input rst_n ,
output reg [3:0] led
);
parameter TIME_US = 6'd50;//50x20=1000ns=1us
parameter TIME_MS = 10'd999;//1usx1000=1ms
parameter TIME_S = 10'd999;//1msx1000=1s
reg [5:0] cnt_us;
reg [9:0] cnt_ms;
reg [9:0] cnt_s;
reg flag;
wire add_cnt_us;//开始计数的标志
wire end_cnt_us;//结束计数的标志
wire add_cnt_ms;
wire end_cnt_ms;
wire add_cnt_s;
wire end_cnt_s;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_us <= 6'd0;
end
else if(add_cnt_us)begin
if(end_cnt_us)begin
cnt_us <= 6'd0;
end
else begin
cnt_us <= cnt_us + 1'd1;
end
end
else begin
cnt_us <= cnt_us;
end
end
assign add_cnt_us = 1'b1;
assign end_cnt_us = add_cnt_us && cnt_us == TIME_US;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_ms <= 10'd0;
end
else if(add_cnt_ms)begin
if(end_cnt_ms)begin
cnt_ms <= 10'd0;
end
else begin
cnt_ms <= cnt_ms + 1'd1;
end
end
else begin
cnt_ms <= cnt_ms;
end
end
assign add_cnt_ms = end_cnt_us;
assign end_cnt_ms = add_cnt_ms && cnt_ms == TIME_MS;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_s <= 10'd0;
end
else if(add_cnt_s)begin
if(end_cnt_s)begin
cnt_s <= 10'd0;
end
else begin
cnt_s <= cnt_s + 1'd1;
end
end
else begin
cnt_s <= cnt_s;
end
end
assign add_cnt_s = end_cnt_ms;
assign end_cnt_s = add_cnt_s && cnt_s == TIME_S;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
flag <= 1'b0;
end
else if(end_cnt_s)begin
flag <= ~flag;
end
else begin
flag <= flag;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
led <= 4'b0000;
end
else if(!flag)begin//flag=0,led由灭到亮
led <= {cnt_s > cnt_ms,cnt_s > cnt_ms,cnt_s > cnt_ms,cnt_s > cnt_ms};
end
else if(flag)begin//flag=1,led由亮到灭
led <= {cnt_s < cnt_ms,cnt_s < cnt_ms,cnt_s < cnt_ms,cnt_s < cnt_ms};
end
else begin
led <= led;
end
end
endmodule
3.2 引脚配置
四、仿真
4.1 仿真代码
`timescale 1ns/1ns
module pwm_led_tb();
reg clk;
reg rst_n;
wire [3:0] led;
parameter CYCLE = 20;
parameter TIME_US = 5;
parameter TIME_MS = 10;
parameter TIME_S = 10;
always #(CYCLE/2) clk = ~clk;
initial begin
clk = 1'b0;
rst_n = 1'b0;
#(CYCLE);
rst_n = 1'b1;
#(2*(TIME_US+1)*(TIME_MS+1)*(TIME_S+1)*CYCLE);
$stop;
end
pwm_led #(
.TIME_US (TIME_US),
.TIME_MS (TIME_MS),
.TIME_S (TIME_S)
) u_pwm_led(
.clk (clk),
.rst_n (rst_n),
.led (led)
);
endmodule
4.2 仿真结果
五、实验结果
六、总结
本次实验主要是需要理解呼吸灯实现的原理,这里我们采用了三个计数寄存器,从us计到ms再到s,最后通过判断s计数器大于ms计数器的时间来决定led亮的时间,这样就可以实现led由暗到亮的效果。