You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.4 KiB
Verilog

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

module traffic_light(
input wire sys_clk ,
input wire sys_rst_n ,
output reg [3: 0] led
);
parameter MAX_S = 26'd50_000_000;//1s
parameter MAX_83 = 7'd83;//83s
//状态空间,自然数编码
parameter IDLE = 2'd0,
RED = 2'd1,
GREEN = 2'd2,
YELLOW = 2'd3;
//动作空间
parameter ACT1 = 4'b0000,
ACT2 = 4'b0100,
ACT3 = 4'b0010,
ACT4 = 4'b0001;
reg [1: 0] c_state;//现态current state
reg [1: 0] n_state;//次态next state
reg [25: 0] cnt_s;//1s计数寄存器
reg [6: 0] cnt_83;//83s计数寄存器
wire start;//进入红绿灯场景标志
assign start = 1'b1;
//约束cnt_s
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)begin
cnt_s <= 26'd0;
end
else if(cnt_s == MAX_S - 1'd1)begin
cnt_s <= 26'd0;
end
else begin
cnt_s <= cnt_s + 1'd1;
end
end
//约束cnt_83
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
cnt_83 <= 7'd0;
end
//计到83-1并且计1s
else if((cnt_83 == MAX_83 - 1'd1) && (cnt_s == MAX_S - 1'd1))begin
cnt_83 <= 7'd0;
end
//每计1s加1
else if(cnt_s == MAX_S - 1'd1)begin
cnt_83 <=cnt_83 + 1'd1;
end
//其他时刻保持
else begin
cnt_83 <= cnt_83;
end
end
//三段式有限状态机,第一段,时序逻辑
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
c_state <= IDLE;//初始化当前状态为IDLE
end
else begin
c_state <= n_state;//其他时钟上升沿,次态赋给现态
end
end
//第二段,组合逻辑,描述状态跳转关系
always @(*)begin
case(c_state)
IDLE : begin
if(start == 1'b1)begin//条件
n_state = RED;//跳转至下一个状态
end
else begin
n_state = IDLE;//保持当前状态
end
end
RED : begin
if((cnt_83 == 7'd59) && (cnt_s == MAX_S - 1'd1))begin
n_state = GREEN;
end
else begin
n_state = RED;
end
end
GREEN : begin
if((cnt_83 == 7'd79) && (cnt_s == MAX_S - 1'd1))begin
n_state = YELLOW;
end
else begin
n_state = GREEN;
end
end
YELLOW : begin
if((cnt_83 == MAX_83 - 1'd1) && (cnt_s == MAX_S - 1'd1))begin
n_state = RED;
end
else begin
n_state = YELLOW;
end
end
default : begin
n_state = IDLE;
end
endcase
end
//第三段,可以组合也可以时序
always@(*)begin
case(c_state)
IDLE : led = ACT1;
RED : led = ACT2;
GREEN : led = ACT3;
YELLOW : led = ACT4;
default : led = ACT1;
endcase
end
endmodule