实验十 简易交通灯
本节将向您介绍Verilog语 法之中的精髓内容——状态机,并且将利用状态机实现十字路口的交通灯。
1. 硬件说明与实现项目框图

上图为十字路口交通示意图分之路与主路,要求如下:
- 交通灯主路上绿灯持续15s的时间,黄灯3s的时间,红灯10s的时间;
- 交通灯支路上绿灯持续7s的时间, 黄灯持续3秒的时间,红灯18秒的时间;

根据上述要求,状态机设计框架分析如下:
- S1:主路绿灯点亮,支路红灯点亮,持续15s的时间;
- S2:主路黄灯点亮,支路红灯点亮,持续3s的时间;
- S3:主路红灯点亮,支路绿灯点亮,持续10s的时间;
- S4:主路红灯点亮,支路黄灯点亮,持续3s的时间;

2. Verilog代码
工程中会用到之前实验的分频模块,以STEP-MXO2上的2个红绿蓝三色LED代表十字路口的红绿黄交通灯。
接下来就 是利用三段式状态机实现的交通灯部分:
module traffic
(
clk , //时钟
rst_n , //复位
out //三色led代表交通灯
);
input clk,rst_n;
output reg[5:0] out;
parameter S1 = 4'b00, //状态机状态编码
S2 = 4'b01,
S3 = 4'b10,
S4 = 4'b11;
parameter time_s1 = 4'd15, //计时参数
time_s2 = 4'd3,
time_s3 = 4'd10,
time_s4 = 4'd3;
//交通灯的控制
parameter led_s1 = 6'b101011, // LED2 绿色 LED1 红色
led_s2 = 6'b110011, // LED2 蓝色 LED1 红色
led_s3 = 6'b011101, // LED2 红色 LED1 绿色
led_s4 = 6'b011110; // LED2 红色 LED1 蓝色
reg [3:0] timecont;
reg [1:0] cur_state,next_state; //现态、次态
wire clk1h; //1Hz时钟
//产生1秒的时钟周期
divide #(.WIDTH(32),.N(12000000)) CLK1H (
.clk(clk),
.rst_n(rst_n),
.clkout(clk1h));
//第一段 同步逻辑 描述次态到现态的转移
always @ (posedge clk1h or negedge rst_n)
begin
if(!rst_n)
cur_state <= S1;
else
cur_state <= next_state;
end
//第二段 组合逻辑描述状态转移的判断
always @ (cur_state or rst_n or timecont)
begin
if(!rst_n) begin
next_state = S1;
end
else begin
case(cur_state)
S1:begin
if(timecont==1)
next_state = S2;
else
next_state = S1;
end
S2:begin
if(timecont==1)
next_state = S3;
else
next_state = S2;
end
S3:begin
if(timecont==1)
next_state = S4;
else
next_state = S3;
end
S4:begin
if(timecont==1)
next_state = S1;
else
next_state = S4;
end
default: next_state = S1;
endcase
end
end
//第三段 同步逻辑 描述次态的输出动作
always @ (posedge clk1h or negedge rst_n)
begin
if(!rst_n==1) begin
out <= led_s1;
timecont <= time_s1;
end
else begin
case(next_state)
S1:begin
out <= led_s1;
if(timecont == 1)
timecont <= time_s1;
else
timecont <= timecont - 1;
end
S2:begin
out <= led_s2;
if(timecont == 1)
timecont <= time_s2;
else
timecont <= timecont - 1;
end
S3:begin
out <= led_s3;
if(timecont == 1)
timecont <= time_s3;
else
timecont <= timecont - 1;
end
S4:begin
out <= led_s4;
if(timecont == 1)
timecont <= time_s4;
else
timecont <= timecont - 1;
end
default:begin
out <= led_s1;
end
endcase
end
end
endmodule
3. 引脚分配
信号 | 引脚 | 信号 | 引脚 |
---|---|---|---|
clk | C1 | rst | L14 |
out[0] | P2 | out[3] | P4 |
out[1] | N2 | out[4] | N3 |
out[2] | M2 | out[5] | M3 |
配置好以后编译下载程序。您也可以试试修改程序,观察修改代码对于FPGA内部电路所造成的影响。
4. 小结
状态机是一类很重要的时序逻辑电路,是许多数字系统的核心部件,掌握状态机的使用是利用FPGA与CPLD进行开发的一项必会技能,本小节的交通灯程序即是利用三段式状态机描述方法实现的,希望读者能够快速掌握这项技能。