红绿灯设计

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
原文地址:https://www.cnblogs.com/luxinshuo/p/13552078.html