紅綠燈設計

 

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章