手撕代码:交通信号灯控制器(乐鑫)
1、题目要求
按下述规则,设计一个十字交叉路口的四向(为表述方便,简化为东西向和南北向)交通信号灯控制器。
a. 同一直线上的道路使用相同的交通信号,切不考虑左转/右转及行人指示灯。
b. 道路上的装置能检测到距路口150m以内是否有车辆要通行。
c. 如东西向道路上有车辆要通行,而当前绿灯已分配给南北向:
如南北向仍持续有车辆要通行,则15秒后强制将绿灯切换给东西向道路;
如南北向已经没有车辆要通行了,则下一秒即可提前将绿灯切换给东西向道路。
绿灯一旦切换给东西向道路后,将一直保持,直到南北向有车辆要通行,此时按照前述相同的逻辑,一定时间后将绿灯切换给南北向道路。
d. 信号灯改变的顺序为:“红→绿”和“绿→黄→红”,其中黄灯的保持时间为3秒。
e. 当一个方向上信号是绿灯或黄灯时,垂直方向上信号必定是红灯。
要求用状态机实现, 定义状态,画出状态转移图,并用Verilog完整描述该控制模块
2、分析
个人分析过程为:定义好状态,输入输出,条件,再把这些串起来就能把状态机画出来,也就能把代码写出来。
3、状态图和代码
这个代码只是一个思路,仅供参考,没有经过验证,如果有什么问题,希望大家能指正:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/06/09 23:43:04
// Design Name:
// Module Name: deng_control
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module deng_control(
input clk,
input rst_n,
input car_dx,
input car_nb,
input none_car_dx,
input none_car_nb,
input flg_15s,
input flg_3s,
output reg green_dx,
output reg red_dx,
output reg green_nb,
output reg red_nb
);
wire [1:0]car_flg;
reg yellow_dx;
reg yellow_nb;
reg [3:0]state;
assign car_flg={car_dx,car_nb};
parameter s0_idle=4'b0000,s1_green_dx=4'b0001,
s2_yellow_dx=4'b0010,
//s3_red_dx=4'b0011,
s4_green_nb=4'b0100,s5_yellow_nb=4'b0101,
//s6_red_nb=4'b0110,
s7_wait_15s_tonb=4'b0111,s8_wait_15_todx=4'b1000;
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
state<=s0_idle;
green_dx<=1;//初始为东西绿灯
red_dx<=0;
yellow_dx<=0;
green_nb<=0;
red_nb<=1;//南北红灯
yellow_nb<=0;
end
else
begin
case(state)
s0_idle:
case(car_flg)//car_flg={car_dx,car_nb}
2'b00:begin state<=s1_green_dx;green_dx<=1;red_nb<=1;end
2'b01:begin state<=s2_yellow_dx;yellow_dx<=1;red_nb<=1; end
2'b10:begin state<=s1_green_dx; green_dx<=1;red_nb<=1; end
2'b11:begin state<=s7_wait_15s_tonb; green_dx<=1;red_nb<=1; end
endcase
s1_green_dx:
case(car_flg)
2'b00:begin state<=s1_green_dx;green_dx<=1;red_nb<=1; end
2'b01:begin state<=s2_yellow_dx;yellow_dx<=1;red_nb<=1; end
2'b10:begin state<=s1_green_dx;green_dx<=1;red_nb<=1; end
2'b11:begin state<=s7_wait_15s_tonb;green_dx<=1;red_nb<=1; end
endcase
s2_yellow_dx:
if(flg_3s==1)
begin
state<=s4_green_nb;//等效于green_nb s4_green_nb等效 s3_red_dx
red_dx<=1;
green_nb<=1;
end
else
begin
state<=s2_yellow_dx;
yellow_dx<=1;
end
/* s3_red_dx:
//对应到nb就是绿***egin
end */
s4_green_nb:
case(car_flg)//car_flg={car_dx,car_nb}
2'b00:begin green_nb<=1;red_dx<=1;state<=s4_green_nb; end
2'b01:begin green_nb<=1;red_dx<=1;state<=s4_green_nb; end
2'b10:begin state<=s5_yellow_nb;yellow_nb<=1;red_dx<=1; end
2'b11:begin state<=s8_wait_15_todx; green_nb<=1;red_dx<=1; end
endcase
s5_yellow_nb:
if(flg_3s==1)
begin
state<=s1_green_dx;//s1_green_dx s6_red_nb
red_nb<=1;
green_dx<=1;
end
else
begin
yellow_nb<=1;
red_dx<=1;
state<=s5_yellow_nb;
end
s7_wait_15s_tonb:
if(flg_15s==1)
begin
state<=s2_yellow_dx;
yellow_dx<=1;
red_nb<=1;
end
else if(cnt<cnt_15&&none_car_dx==1)
begin
state<=s2_yellow_dx;
yellow_dx<=1;
red_nb<=1;
end
else
begin
state<=s7_wait_15s_tonb;
green_dx<=1;
red_nb<=1;
end
s8_wait_15_todx:
if(flg_15s==1)
begin
state<=s5_yellow_nb;
yellow_nb<=1;
red_dx<=1;
end
else if(cnt<=cnt_15&&none_car_nb)
begin
state<=s5_yellow_nb;
yellow_nb<=1;
red_dx<=1;
end
default:
begin
state<=s0_idle;
green_dx<=1;//初始为东西绿灯
red_dx<=0;
yellow_dx<=0;
green_nb<=0;
red_nb<=1;//南北红灯
yellow_nb<=0;
end
endcase
end
endmodule