大家好,又见面了,我是你们的朋友全栈君。
交通信号灯控制系统的Verilog实现 作为数字系统设计入门案例,下面简单介绍最简单的交通控制系统,说明设计思路。 首先给出要求:设计一个主干道和支干道十字路口的交通信号灯控制电路 (1)一般情况下保持主干道通畅,主干道绿灯亮、支干道红灯亮,并且主干道绿灯亮时间不少于60秒。 (2)主干道绿灯亮超过60秒,且支干道有车时,主干道红灯亮,支干道绿灯亮,但支干道亮灯时间不超过30秒。 (3)每次主干道或支干道绿灯变红灯时,黄灯先亮5秒。 1.逻辑抽象,明确输入输出。 主干道和支干道的十字路口交通灯系统求优先保证主干道的畅通。平时处于主干道绿灯、支干道红灯的状态。当支干道有车时,传感器发出信号S=1,主干道绿灯先转换成黄灯、再变成红灯,支干道由红灯变成绿灯。如果支干道继续有车通过时,则传感器继续有信号,使支干道保持绿灯亮,但支干道绿灯持续亮的时间不得超过30s,否则支干道绿灯先转换成黄灯再变成红灯,同时主干道由红灯变成绿灯。主干道每次通行时间不得短于60s,在此期间,即使支干道S有信号,也不能中止主干道的绿灯亮。 输入信号有时钟、复位、传感器信号;输出有主干道红黄绿灯和支干道红黄绿灯。 2.确定系统框图 首先用状态机作为主控制,状态机转换条件根据计时器信息判断转换条件,译码电路中根据所在状态输出对应干道信号灯状态。 控制单元根据时钟和传感信号向计数器发出信号,计时器向控制单元发出60s(t1)、30s(t2)、5s(t3)计时信号。主干道红黄绿用h_r,h_y,h_g表示,支干道红黄绿用f_r,f_y,f_g表示。
因此,用计时分别产生三个持续的时间段后,向控制单元发出时间已到信号,控制单元根据计时器及传感器的信号,决定是否进行状态转换。如果肯定,则控制单元发出状态转换信号St,计时器开始清零,准备重新计时。
交通灯控制单元的控制过程分为四个阶段,对应的输出有四种状态,分别用S0、S1、S2和S3表示: S0状态 主干道绿灯亮支干道红灯亮,此时若支干道有车等待通过,而且主干道绿灯已亮足规定的时间t1,控制器发出状态转换信号St,输出从状态S0转换到S1 (转换条件:绿灯亮够60s且检测到支干道有车即 t1&&s=1)
S1状态 主干道黄灯亮,支干道红灯亮,进人此状态,黄灯亮足规定的时间t3时,控制器发出状态转换信号St,输出从状态S1转换到S2。 (转换条件:黄灯亮够5s就转换状态即 t3=1)
S2状态 支干道绿灯亮,主干道红灯亮,若此时支干道继续有车,则继续保持此状态,但支干道绿灯亮的时间不得超过t2,否则控制单元发出状态转换信号St,使输出转换到S3状态。若此时支干道没有车,则控制单元立即发出状态转换信号St,使输出转换到S3状态。 (转换条件:支干道绿灯亮够30s或者检测到支干道没车即 t2 (~s)=1)
S3状态 支干道黄灯亮,主干道红灯亮,此时状态与S1状态持续的时间相同均为t3,时间到时,控制器发出St信号,输出从状态S3回到S0状态。对上述S0、S1、S2和S3四种状态按照格雷码进行编码分别为00,01,11和10。 /控制状态机/ always@(posedge clk or negedge rst) begin if(!rst) current_state<=2’d0; else current_state<=next_state; end
代码语言:javascript复制always@(s,current_state,t1,t2,t3)
begin
case(current_state)
s0: begin
next_state=(t1&&s)?s1:s0;
ST=(t1&&s)?1'b1:1'b0;
end
s1: begin
next_state=(t3)?s2:s1;
ST=(t3)?1'b1:1'b0;
end
s2: begin
next_state=(t2||~s)?s3:s2;
ST=(t2||~s)?1'b1:1'b0;
end
s3: begin
next_state=(t3)?s0:s3;
ST=(t3)?1'b1:1'b0;
end
endcase
end
计时部分采用2个寄存器代表十位(t_h)和个位(t_l)计数,同时每次检测到转换信号都要清零重新计时
代码语言:javascript复制always@(posedge clk or negedge rst) //计时模块
begin
if(!rst)
{
t_h,t_l}<=8'd0; else if(ST) //控制信号有效说明灯的颜色改变重新计数 {t_h,t_l}<=8'd0;
else if((t_h==4'd5)&(t_l==4'd9)) //判断是否计数到60
begin
{
t_h,t_l}<={
t_h,t_l};
end
else if(t_l==4'd9) //判断个位是否计数满,是则十位加一 begin t_h<=t_h 1'b1;
t_l<=4'd0; end else begin t_h<=t_h; t_l<=t_l 1'b1;
end
end
assign t3=(t_h==4'd0)&(t_l==4'd4); //主干道绿灯计数时间
assign t2=(t_h==4'd2)&(t_l==4'd9); // 支干道绿灯计数时间
assign t1=(t_h==4'd5)&(t_l==4'd9); //黄灯计数时间
译码部分根据状态机所在状态输出对应信号灯状态
代码语言:javascript复制always@(current_state)
begin
case(current_state)
s0: begin
{
hg,hy,hr}=3'b100; //主干道绿灯 {fg,fy,fr}=3'b001; //支干道红灯
end
s1: begin
{
hg,hy,hr}=3'b010; //主干道黄灯 {fg,fy,fr}=3'b001; //支干道红灯
end
s2: begin
{
hg,hy,hr}=3'b001; //主干道红灯 {fg,fy,fr}=3'b100; //支干道绿灯
end
s3: begin
{
hg,hy,hr}=3'b001; //主干道红灯 {fg,fy,fr}=3'b010; //支干道黄灯
end
endcase
end
仿真结果图 总结:本文设计较简单,对于复杂交通还需改善,但是能够从中慢慢建立对系统架构的认知和联系,从中理清各模块间关系。后续还需多查资料研究,如有错误不合理之处,请告知。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。