[source lang="verilog"] //状态机模块 module sta_machine(clk_div, rst_n, hum_or_car, led_0, led_1); input clk_div, rst_n; input hum_or_car; //一个信号表示有或者车 output reg [1:0] led_0, led_1; //led_0表示主干道,led_1表示从干道,高位为绿灯,低位为红灯 reg blink; //blink用来控制灯的闪烁 reg [3:0] cnt; //对灯亮的时间进行计数 reg cnt_clr; //计数器清零的标志,低电平有效 reg [2:0] cs, ns; //cs表示现态,ns表示次态 localparam s0 = 3'b000, s1 = 3'b001, s2 = 3'b011, s3 = 3'b010, s4= 3'b110, s5 = 3'b101; //描述状态机的现态 always @ (posedge clk_div or negedge rst_n) begin if(!rst_n) begin cs <= s0; cnt <= 0; end else begin cs <= ns; if(!cnt_clr) cnt <= 0; else cnt <= cnt + 1; end end //描述状态机的次态 always @ (cs or hum_or_car or rst_n) begin if(!rst_n) begin ns = s0; cnt_clr = 0; end else begin case(cs) //主路绿灯保持10秒以上且支路有车或行人则进入下一个状态(计数器清零),否则保持状态 s0: begin if((cnt >= 4'd10) && (hum_or_car == 1)) begin ns = s1; cnt_clr = 0; end else begin ns = s0; cnt_clr = 1; end end //主路绿灯闪烁3秒后进入下一个状态(计数器清零),否则保持状态 s1: begin if(cnt >= 4'd3) begin ns = s2; cnt_clr = 0; end else begin ns = s1; cnt_clr = 1; end end //主路支路均为红灯保持3秒后进入下一个状态(计数器清零),否则保持状态 s2: begin if(cnt >= 4'd3) begin ns = s3; cnt_clr = 0; end else begin ns = s2; cnt_clr = 1; end end //支路绿灯主路红灯保持5秒后进入下一个状态(计数器清零),否则保持状态 s3: begin if(cnt >= 4'd5) begin ns = s4; cnt_clr = 0; end else begin ns = s3; cnt_clr = 1; end end //支路绿灯闪烁3秒后进入下一个状态(计数器清零),否则保持状态 s4: begin if(cnt >= 4'd3) begin ns = s5; cnt_clr = 0; end else begin ns = s4; cnt_clr = 1; end end //主路支路均为红灯保持3秒后进入下一个状态(计数器清零),否则保持状态 s5: begin if(cnt >= 4'd3) begin ns = s0; cnt_clr = 0; end else begin ns = s5; cnt_clr = 1; end end endcase end end //描述状态机的输出 always @ (posedge clk_div or negedge rst_n) begin if(!rst_n) begin led_0 <= 2'b00; led_1 <= 2'b00; blink <= 0; end else begin case(ns) s0: begin //主路绿灯,支路红灯 led_0 <= 2'b10; led_1 <= 2'b01; end s1: begin if(!blink) begin //主路绿灯闪烁三秒,支路红灯 led_0 <= 2'b00; led_1 <= 2'b01; blink <= 1; end else begin led_0 <= 2'b10; led_1 <= 2'b01; blink <= 0; end end s2: begin //主路支路皆是红灯 led_0 <= 2'b01; led_1 <= 2'b01; end s3: begin //主路红灯,支路绿灯 led_0 <= 2'b01; led_1 <= 2'b10; end s4: begin if(!blink) begin //主路红灯,支路绿灯闪烁3秒 led_0 <= 2'b01; led_1 <= 2'b00; end else begin led_0 <= 2'b01; led_1 <= 2'b10; end end s5: begin //主路支路皆是红灯 led_0 <= 2'b01; led_1 <= 2'b01; end endcase end end endmodule [/source]