前言
机动车道红绿灯其实就是一个流水灯,只是红绿灯闪烁的间隔不等,一般黄灯3s、红灯60s、绿灯20s。而在流水灯中,设置闪烁的间隔时间是相等的。
一、实验目的
使用Cyclone IV开发板上的3个led灯实现红绿灯功能。
二、设计规范(需求)
从红灯开始,红灯60s、黄灯3s、绿灯20s。编写代码,实现红绿灯的功能。
三、原理图
四、设计输入
- 编写sec_count.v,实现基本计时器,记录1s
module sec_count(
input wire clk,//时钟信号
input wire rst_n,//复位信号,下降沿有效
output wire sec//秒钟脉冲
);
parameter MAX_NUM = 26'd49_999_999;//记1s
reg [25:0] cnt;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 26'd0;
end
else if(cnt == MAX_NUM)begin
cnt <= 26'd0;
end
else begin
cnt <= cnt + 1'd1;
end
end
assign sec = cnt == MAX_NUM ? 1'b1 : 1'b0;//1s脉冲输出
endmodule
- 编写count_83s.v文件,实现83s计时器,记录红绿灯总时间
module count_83s(
input wire clk,//时钟信号
input wire rst_n,//复位信号,下降沿有效
input wire sec,//1s脉冲信号
output reg [2:0] led//3个led灯
);
parameter MAX_SEC = 7'd82;//总共83s,60+3+20
parameter RED = 6'd59;//60s,红灯
parameter YELLOW = 6'd62;//3s,黄灯
parameter GREEN = 7'd82;//20s,绿灯
reg [6:0] cnt_sec;//红绿灯计数寄存器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_sec <= 7'd0;
end
else if(cnt_sec == MAX_SEC)begin
cnt_sec <= 7'd0;
end
else if(sec)begin//满足1s钟
cnt_sec <= cnt_sec + 1'd1;
end
else begin
cnt_sec <= cnt_sec;
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
led <= 3'b001;//初始化红灯
end
else if(cnt_sec == RED)begin//红灯结束
led <= 3'b010;//黄灯亮
end
else if(cnt_sec == YELLOW)begin//黄灯结束
led <= 3'b100;//绿灯亮
end
else if(cnt_sec == GREEN)begin//绿灯结束
led <= 3'b001;//红灯亮
end
else begin
led <= led;//中间时刻保持状态
end
end
endmodule
- 编写light_led_top.v顶层文件,调用1、2中的模块
module light_led_top(
input wire clk,//时钟信号
input wire rst_n,//复位信号,下降沿有效
output wire [2:0] led//4个led信号
);
wire sec;
parameter MAX_NUM = 26'd49_999_999;
//实例化计时1s钟模块
sec_count#(.MAX_NUM (MAX_NUM)) u_sec_count(
.clk (clk),
.rst_n (rst_n),
.sec (sec)
);
//实例化红绿灯控制模块
count_83s u_count_83s(
.clk (clk),
.rst_n (rst_n),
.sec (sec),
.led (led)
);
endmodule
五、红绿灯仿真
- 编写sec_count_tb.v文件,调用顶层模块进行仿真
`timescale 1ns/1ns
module sec_count_tb();
//激励信号定义
reg clk ;
reg rst_n;
//输出信号定义
wire [2:0] led;
//时钟周期参数定义
parameter CLOCK_CYCLE = 5'd20;//时钟周期
parameter MAX_NUM = 4'd9;//基本计时器改小,便于观察信号,时间10x20=200ns
//产生时钟
always #(CLOCK_CYCLE/2) clk = ~clk;
//产生激励
initial begin
clk = 1'b0 ;
rst_n = 1'b0 ;
#(CLOCK_CYCLE) ;
rst_n = 1'b1 ;
#(CLOCK_CYCLE*MAX_NUM*100);
$stop ;
end
light_led_top#(.MAX_NUM (MAX_NUM)) u_light_led_top(
.clk (clk),
.rst_n(rst_n),
.led (led)
);
endmodule
- 仿真结果
总结
技术来源于生活,只有你想不到,没有你做不到。格局打开,接下来可以使用有限状态机实现红绿灯了!