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.
|
|
|
|
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
|