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