module hld(
input clk,
input rst_n,
input nb_beg, //南北方向同行请求
input dx_beg, //东西方向同行请求
output reg nb_red, //南北方向红灯
output reg nb_green, //南北方向绿灯
output reg nb_yellow, //南北方向黄灯
output reg dx_red, //东西方向红灯
output reg dx_green, //东西方向绿灯
output reg dx_yellow //东西方向黄灯
);
reg [5:0] state;
parameter NB = 6'b000_001, //南北通行状态
NB_led = 6'b000_010, //要到达南北通行
DX = 6'b000_100, //东西通行状态
DX_led = 6'b001_000, //要达到东西通行
NB_15s = 6'b010_000, //当前为南北方向通行,检测到东西方向通行请求且有车
DX_15s = 6'b100_000; //当前为东西方向通行,检测到南北方向通行请求且有车
parameter CNT_MAX=50_000_000-1'b1; //计数最大值
reg [31:0]nb_cnt; //当前为南北方向通行,计数
reg [31:0]dx_cnt; //当前为东西方向通行,计数
reg cnt_en; // 计数使能
reg[31:0]cnt_1s;
//在计数使能时,计数到最大值时为1s
always@(posedge clk or negedge rst_n)
if(~rst_n)
cnt_1s<=32'd0;
else if(cnt_en)
begin
if(cnt_1s==CNT_MAX)
cnt_1s<=32'd0;
else
cnt_1s<=cnt_1s+1'b1;
end
else
cnt_1s<=32'd0;
wire sec_plus;
assign sec_plus = cnt_1s==CNT_MAX; //一秒的脉冲
reg [3:0]cnt; //秒计数器
reg [3:0]last_state;
//线性序列机思想实现灯亮灭控制
always@(posedge clk or negedge rst_n)
if(~rst_n)
begin
state <=NB ; //复位后南北通行状态
// last_state<=NB;
end
else
begin
case (state)
NB_led: //要到达南北通行状态
begin
cnt_en<=1'b1;
if(sec_plus)
begin
if(cnt==3)
begin
cnt<=0;
state<=NB;
cnt_en<=1'b0;
end
else
cnt<=cnt+1'b1;
end
if(cnt==3)
begin
{nb_red,nb_green,nb_yellow}<=3'b010; //南北绿灯亮
{dx_red,dx_green,dx_yellow}<=3'b010; //东西黄灯灭 红灯亮
end
else if(cnt<3)
begin
{nb_red,nb_green,nb_yellow}<=3'b100; //南北红灯亮
{dx_red,dx_green,dx_yellow}<=3'b001; //东西黄灯亮3s
end
end
NB: //南北方向通行
begin
if(dx_beg&&!nb_beg) //东西方向通行请求 南北方向无车
state<=DX_led;
else if(dx_beg&nb_beg) //东西方向通行请求 南北方向有车
state<=DX_15s;
end
DX_led: //要到达东西通行状态
begin
cnt_en<=1'b1; //开启计数使能
if(sec_plus) begin
if(cnt==3)
begin
cnt<=0;
state<=DX;
cnt_en<=1'b0;
end
else
cnt<=cnt+1'b1;
end
if(cnt==3)
begin
{nb_red,nb_green,nb_yellow}<=3'b100; //南北红灯亮
{dx_red,dx_green,dx_yellow}<=3'b010; //东西黄灯灭绿灯亮
end
else if(cnt<3)
begin
{nb_red,nb_green,nb_yellow}<=3'b001; //南北黄灯亮3s
{dx_red,dx_green,dx_yellow}<=3'b100; //东西红灯亮
end
end
DX: //东西方向通行
begin
if(~dx_beg&&nb_beg) //南北方向通行请求 东西方向无车
state<=NB_led;
else if(dx_beg&nb_beg) //东西方向通行请求 南北方向有车
state<=NB_15s;
end
NB_15s: //要到达南北通行,因为东西正在有车通行,先计数15s
begin
cnt_en<=1'b1;
if(sec_plus)
begin
if(cnt==15)
begin
cnt<=0;
cnt_en<=1'b0;
state<=NB_led;
end
else
begin
cnt<=cnt+1'b1;
end
end
end
DX_15s: //要到达东西通行,因为南北正在有车通行,先计数15s
begin
cnt_en<=1'b1;
if(sec_plus)
begin
if(cnt==15)
begin
cnt<=0;
cnt_en<=1'b0;
state<=DX_led;
end
else
cnt<=cnt+1'b1;
end
end
default:;
endcase
end
endmodule