用FPGA设计交通灯,怎么实现紧急情况

2019-03-25 08:44发布

最好有代码,越详细越好。谢谢了 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
Crazy_HUA
1楼-- · 2019-03-25 19:43
 精彩回答 2  元偷偷看……
华克钊
2楼-- · 2019-03-26 01:39
紧急情况就是红灯全亮,数码管减计数停止,用按键控制
华克钊
3楼-- · 2019-03-26 06:09
module trafic_lambp(clk,sm_bit,sm_seg,en,rst,light1,light2,sw1_n);
input clk;//定义时钟引脚
input rst,en; //定义复位和使能引脚
input sw1_n;
output [3:0]sm_bit;//定义数码管位选引脚
output [7:0]sm_seg;//定义数码管段选引脚
output[2:0]light1,light2;//定义两个方向交通灯

reg [3:0]sm_bit_r;
reg [7:0]sm_seg_r;
reg [7:0]disp_dat;//定义数码管显示数据寄存器
reg[24:0]count;//定义计数器寄存器
reg sec;//定义秒信号寄存器
reg tim1,tim2;//定义tim1位倒计时是否到达的位标识
  
reg[1:0]state1,state2;//定义一些状态
reg[2:0]light1,light2;
reg[7:0]num1,num2;//num1和num2的值为倒计时的值
reg[7:0]red1,red2,green1,green2,yellow1,yellow2;//定义红黄蓝灯的一些状态

assign sm_bit=sm_bit_r;
assign sm_seg=sm_seg_r;
  
//-----------------------------------------------------
always@(posedge clk)
     begin count=count+1'b1;
          if(count==25'd25000000 && d1==1'b0)//时间达到一秒  
          begin  
            count=25'd0;  
            sec=~sec;
          end
     end
//-----------------------------------------------------      
always@(posedge clk)         
      begin  
         case (count[17:15])
         3'd0:disp_dat = num1[3:0];//秒个位   
         3'd1:disp_dat = num1[7:4];   //秒十位   
         //3'd2:disp_dat = 4'ha;    //显示"-"   
         3'd3:disp_dat = num2[3:0];   //分个位   
         3'd4:disp_dat = num2[7:4];  //分十位
         //3'd5:disp_dat = 4'ha;    //显示"-"      
        endcase        
        case(count[17:15])      //选择数码管显示位  
          3'd0:sm_bit_r = 4'b1110;   //选择第一个数码管显示
          3'd1:sm_bit_r = 4'b1101;   //选择第二个数码管显示
          //3'd2:sm_bit_r = 8'b11111011;   //选择第三个数码管显示   
          3'd3:sm_bit_r = 4'b1011;   //选择第四个数码管显示   
          3'd4:sm_bit_r = 4'b0111;   //选择第五个数码管显示   
          //3'd5:sm_bit_r = 8'b11011111;   //选择第六个数码管显示   
          //3'd6:sm_bit_r = 8'b10111111;   //选择第七个数码管显示   
          //3'd7:sm_bit_r = 8'b01111111;   //选择第八个数码管显示  
         endcase      
       end
//-----------------------------------------------------           
always @(posedge clk)  
       begin  
        case(disp_dat)   
         4'h0:sm_seg_r = 8'h3f;     //显示0   
         4'h1:sm_seg_r = 8'h06;     //显示1   
         4'h2:sm_seg_r = 8'h5b;     //显示2   
         4'h3:sm_seg_r = 8'h4f;     //显示3   
         4'h4:sm_seg_r = 8'h66;     //显示4   
         4'h5:sm_seg_r = 8'h6d;     //显示5   
         4'h6:sm_seg_r = 8'h7d;     //显示6   
         4'h7:sm_seg_r = 8'h07;     //显示7   
         4'h8:sm_seg_r = 8'h7f;     //显示8   
         4'h9:sm_seg_r = 8'h6f;     //显示9   
         //4'ha:sm_seg_r = 8'hbf;     //显示-   
         default:sm_seg_r = 8'h00;    //不显示  
        endcase   
       end
//-----------------------------------------------------               
always@(en)
    if(!en)
      begin        
         green1<=8'b00100101;
         red1<=8'b00010000;
         yellow1<=8'd5;
         green2<=8'b00010000;
         red2<=8'b00100101;
         yellow2<=8'd5;
       end
               
always@(posedge sec)//南北方向      
      begin   
         if(!rst)//复位模块   
            begin   
             light1<=3'b001;   
             num1<=green1;   
            end   
         if(!tim1)     
          begin   
           tim1<=1;   
        case(state1)   
         2'b00:begin
                                  num1<=green1;
                                  light1<=3'b011;
                                  state1<=2'b01;
               end
         2'b01:begin
                                  num1<=yellow1;
                                  light1<=3'b011;
                                  state1<=2'b11;
               end   
         2'b11:begin
                                  num1<=red1;
                                  light1<=3'b110;
                                  state1<=2'b10;
                                end   
         2'b10:begin
                                  num1<=yellow1;
                                  light1<=3'b101;
                                  state1<=2'b00;
                                end//状态机使三个状态一直循环   
        default:light1<=3'b011;   
          endcase   
          end     
         else     
           begin      
                                 if(num1==1) begin tim1<=0; num1 <= 0;end   
                                 else if(num1>0)   
                                 if(num1[3:0]==0)   
                                 begin   
                                 num1[3:0]<=4'b1001;//倒计时模块   
                                 num1[7:4]<=num1[7:4]-1;   
                                 end   
                                 else num1[3:0]<=num1[3:0]-1;           
            end   
            end      

always@(posedge sec)//东西方向      
      begin   
              if(!rst)//复位模块     
              begin     
              light2<=3'b100;     
              num2<=red2;     
              end     
              if(!tim2)      
              begin   
              tim2<=1;   
              case(state2)   
              2'b00:begin
                     num2<=red2;
                     light2<=3'b110;
                     state2<=2'b01;
                    end   
              2'b01:begin  
                     num2<=yellow1;
                     light2<=3'b101;
                     state2<=2'b11;
                    end   
              2'b11:begin
                      num2<=green2;
                      light2<=3'b011;
                      state2<=2'b10;
                    end   
              2'b10:begin
                      num2<=yellow2;
                      light2<=3'b011;
                     state2<=2'b00;
                    end   
              default:light2<=3'b011;   
              endcase   
              end   
          else     
          begin      
             if(num2==1)begin tim2<=0;num2<=0;end   
             else if(num2>0)   
             if(num2[3:0]==0)   
             begin   
             num2[3:0]<=4'b1001;   
             num2[7:4]<=num2[7:4]-1;   
             end   
             else num2[3:0]<=num2[3:0]-1;           
          end   
     end     
//-----------------------------------------------------
         
reg key_rst;
     always @(posedge clk or negedge rst)
         if(!rst) key_rst<=1'b1;
         else key_rst<={sw1_n};
reg key_rst_r;
     always @(posedge clk or negedge rst)
        if(!rst) key_rst_r<=1'b1;
         else key_rst_r<=key_rst;
wire key_an=key_rst_r & (~key_rst);
        //  key_rst   111001
        //   ~key_rst   000110
         //  key_rst   111001
          // key_n       00100  
reg[19:0] cnt;
       always @(posedge clk or negedge rst)
          if(!rst) cnt<=20'd0;
          else if(key_an) cnt<=20'd0;
              else cnt<=cnt+1'b1;
reg low_sw;
       always @(posedge clk or negedge rst)
          if(!rst) low_sw<=1'b1;
          else if(cnt==20'hfffff)
          low_sw<=sw1_n;
reg low_sw_r;      
         always @(posedge clk or negedge rst)
          if(!rst) low_sw_r<=1'b0;
          else low_sw_r<=low_sw;
wire led_ctrl=low_sw_r&(~low_sw);
       reg d1;  
       always @(posedge clk or negedge rst)
     if(!rst)
         begin
         d1<=1'b0;
         end
     else
         begin
         if(led_ctrl) d1<=~d1;
         end
endmodule      
            
         
         
         
         
         
         
         
         
         module trafic_lambp(clk,sm_bit,sm_seg,en,rst,light1,light2,sw1_n);
input clk;//定义时钟引脚
input rst,en; //定义复位和使能引脚
input sw1_n;
output [3:0]sm_bit;//定义数码管位选引脚
output [7:0]sm_seg;//定义数码管段选引脚
output[2:0]light1,light2;//定义两个方向交通灯

reg [3:0]sm_bit_r;
reg [7:0]sm_seg_r;
reg [7:0]disp_dat;//定义数码管显示数据寄存器
reg[24:0]count;//定义计数器寄存器
reg sec;//定义秒信号寄存器
reg tim1,tim2;//定义tim1位倒计时是否到达的位标识
  
reg[1:0]state1,state2;//定义一些状态
reg[2:0]light1,light2;
reg[7:0]num1,num2;//num1和num2的值为倒计时的值
reg[7:0]red1,red2,green1,green2,yellow1,yellow2;//定义红黄蓝灯的一些状态

assign sm_bit=sm_bit_r;
assign sm_seg=sm_seg_r;
  
//-----------------------------------------------------
always@(posedge clk)
     begin count=count+1'b1;
          if(count==25'd25000000 && d1==1'b0)//时间达到一秒  
          begin  
            count=25'd0;  
            sec=~sec;
          end
     end
//-----------------------------------------------------      
always@(posedge clk)         
      begin  
         case (count[17:15])
         3'd0:disp_dat = num1[3:0];//秒个位   
         3'd1:disp_dat = num1[7:4];   //秒十位   
         //3'd2:disp_dat = 4'ha;    //显示"-"   
         3'd3:disp_dat = num2[3:0];   //分个位   
         3'd4:disp_dat = num2[7:4];  //分十位
         //3'd5:disp_dat = 4'ha;    //显示"-"      
        endcase        
        case(count[17:15])      //选择数码管显示位  
          3'd0:sm_bit_r = 4'b1110;   //选择第一个数码管显示
          3'd1:sm_bit_r = 4'b1101;   //选择第二个数码管显示
          //3'd2:sm_bit_r = 8'b11111011;   //选择第三个数码管显示   
          3'd3:sm_bit_r = 4'b1011;   //选择第四个数码管显示   
          3'd4:sm_bit_r = 4'b0111;   //选择第五个数码管显示   
          //3'd5:sm_bit_r = 8'b11011111;   //选择第六个数码管显示   
          //3'd6:sm_bit_r = 8'b10111111;   //选择第七个数码管显示   
          //3'd7:sm_bit_r = 8'b01111111;   //选择第八个数码管显示  
         endcase      
       end
//-----------------------------------------------------           
always @(posedge clk)  
       begin  
        case(disp_dat)   
         4'h0:sm_seg_r = 8'h3f;     //显示0   
         4'h1:sm_seg_r = 8'h06;     //显示1   
         4'h2:sm_seg_r = 8'h5b;     //显示2   
         4'h3:sm_seg_r = 8'h4f;     //显示3   
         4'h4:sm_seg_r = 8'h66;     //显示4   
         4'h5:sm_seg_r = 8'h6d;     //显示5   
         4'h6:sm_seg_r = 8'h7d;     //显示6   
         4'h7:sm_seg_r = 8'h07;     //显示7   
         4'h8:sm_seg_r = 8'h7f;     //显示8   
         4'h9:sm_seg_r = 8'h6f;     //显示9   
         //4'ha:sm_seg_r = 8'hbf;     //显示-   
         default:sm_seg_r = 8'h00;    //不显示  
        endcase   
       end
//-----------------------------------------------------               
always@(en)
    if(!en)
      begin        
         green1<=8'b00100101;
         red1<=8'b00010000;
         yellow1<=8'd5;
         green2<=8'b00010000;
         red2<=8'b00100101;
         yellow2<=8'd5;
       end
               
always@(posedge sec)//南北方向      
      begin   
         if(!rst)//复位模块   
            begin   
             light1<=3'b001;   
             num1<=green1;   
            end   
         if(!tim1)     
          begin   
           tim1<=1;   
        case(state1)   
         2'b00:begin
                                  num1<=green1;
                                  light1<=3'b011;
                                  state1<=2'b01;
               end
         2'b01:begin
                                  num1<=yellow1;
                                  light1<=3'b011;
                                  state1<=2'b11;
               end   
         2'b11:begin
                                  num1<=red1;
                                  light1<=3'b110;
                                  state1<=2'b10;
                                end   
         2'b10:begin
                                  num1<=yellow1;
                                  light1<=3'b101;
                                  state1<=2'b00;
                                end//状态机使三个状态一直循环   
        default:light1<=3'b011;   
          endcase   
          end     
         else     
           begin      
                                 if(num1==1) begin tim1<=0; num1 <= 0;end   
                                 else if(num1>0)   
                                 if(num1[3:0]==0)   
                                 begin   
                                 num1[3:0]<=4'b1001;//倒计时模块   
                                 num1[7:4]<=num1[7:4]-1;   
                                 end   
                                 else num1[3:0]<=num1[3:0]-1;           
            end   
            end      

always@(posedge sec)//东西方向      
      begin   
              if(!rst)//复位模块     
              begin     
              light2<=3'b100;     
              num2<=red2;     
              end     
              if(!tim2)      
              begin   
              tim2<=1;   
              case(state2)   
              2'b00:begin
                     num2<=red2;
                     light2<=3'b110;
                     state2<=2'b01;
                    end   
              2'b01:begin  
                     num2<=yellow1;
                     light2<=3'b101;
                     state2<=2'b11;
                    end   
              2'b11:begin
                      num2<=green2;
                      light2<=3'b011;
                      state2<=2'b10;
                    end   
              2'b10:begin
                      num2<=yellow2;
                      light2<=3'b011;
                     state2<=2'b00;
                    end   
              default:light2<=3'b011;   
              endcase   
              end   
          else     
          begin      
             if(num2==1)begin tim2<=0;num2<=0;end   
             else if(num2>0)   
             if(num2[3:0]==0)   
             begin   
             num2[3:0]<=4'b1001;   
             num2[7:4]<=num2[7:4]-1;   
             end   
             else num2[3:0]<=num2[3:0]-1;           
          end   
     end     
//-----------------------------------------------------
         
reg key_rst;
     always @(posedge clk or negedge rst)
         if(!rst) key_rst<=1'b1;
         else key_rst<={sw1_n};
reg key_rst_r;
     always @(posedge clk or negedge rst)
        if(!rst) key_rst_r<=1'b1;
         else key_rst_r<=key_rst;
wire key_an=key_rst_r & (~key_rst);
        //  key_rst   111001
        //   ~key_rst   000110
         //  key_rst   111001
          // key_n       00100  
reg[19:0] cnt;
       always @(posedge clk or negedge rst)
          if(!rst) cnt<=20'd0;
          else if(key_an) cnt<=20'd0;
              else cnt<=cnt+1'b1;
reg low_sw;
       always @(posedge clk or negedge rst)
          if(!rst) low_sw<=1'b1;
          else if(cnt==20'hfffff)
          low_sw<=sw1_n;
reg low_sw_r;      
         always @(posedge clk or negedge rst)
          if(!rst) low_sw_r<=1'b0;
          else low_sw_r<=low_sw;
wire led_ctrl=low_sw_r&(~low_sw);
       reg d1;  
       always @(posedge clk or negedge rst)
     if(!rst)
         begin
         d1<=1'b0;
         end
     else
         begin
         if(led_ctrl) d1<=~d1;
         end
endmodule      
            
这个是我写的程序还缺紧急状态
eeleader
4楼-- · 2019-03-26 08:50
先把原理搞清楚吧.
3637320230
5楼-- · 2019-03-26 11:13
华克钊
6楼-- · 2019-03-26 13:16
你帮我看看,这个加了按键,按下的时候是红灯灯都亮,减计数停,但是再按一下按键那个灯不恢复正常状态
代码:module trafic_lambp(clk,sm_bit,sm_seg,en,rst,light1,light2,sw1_n);
input clk;//定义时钟引脚
input rst,en; //定义复位和使能引脚
input sw1_n;
output [3:0]sm_bit;//定义数码管位选引脚
output [7:0]sm_seg;//定义数码管段选引脚
output[2:0]light1,light2;//定义两个方向交通灯

reg [3:0]sm_bit_r;
reg [7:0]sm_seg_r;
reg [7:0]disp_dat;//定义数码管显示数据寄存器
reg[24:0]count;//定义计数器寄存器
reg sec;//定义秒信号寄存器
reg tim1,tim2;//定义tim1位倒计时是否到达的位标识
  
reg[1:0]state1,state2;//定义一些状态
reg[2:0]light1,light2;
reg[7:0]num1,num2;//num1和num2的值为倒计时的值
reg[7:0]red1,red2,green1,green2,yellow1,yellow2;//定义红黄蓝灯的一些状态

assign sm_bit=sm_bit_r;
assign sm_seg=sm_seg_r;
  
//-----------------------------------------------------
always@(posedge clk)
     begin count=count+1'b1;
          if(count==25'd12500000 )//产生1HZ的时钟信号
          begin  
            count=25'd0;  
            sec=~sec;
          end
     end
//-----------------------------------------------------      
always@(posedge clk)         
      begin  
         case (count[17:15])
         3'd0:disp_dat = num1[3:0];//秒个位   
         3'd1:disp_dat = num1[7:4];   //秒十位   
         //3'd2:disp_dat = 4'ha;    //显示"-"   
         3'd3:disp_dat = num2[3:0];   //分个位   
         3'd4:disp_dat = num2[7:4];  //分十位
         //3'd5:disp_dat = 4'ha;    //显示"-"      
        endcase        
        case(count[17:15])      //选择数码管显示位  
          3'd0:sm_bit_r = 4'b1110;   //选择第一个数码管显示
          3'd1:sm_bit_r = 4'b1101;   //选择第二个数码管显示
          //3'd2:sm_bit_r = 8'b11111011;   //选择第三个数码管显示   
          3'd3:sm_bit_r = 4'b1011;   //选择第四个数码管显示   
          3'd4:sm_bit_r = 4'b0111;   //选择第五个数码管显示   
          //3'd5:sm_bit_r = 8'b11011111;   //选择第六个数码管显示   
          //3'd6:sm_bit_r = 8'b10111111;   //选择第七个数码管显示   
          //3'd7:sm_bit_r = 8'b01111111;   //选择第八个数码管显示  
         endcase      
       end
//-----------------------------------------------------           
always @(posedge clk)  
       begin  
        case(disp_dat)   
         4'h0:sm_seg_r = 8'h3f;     //显示0   
         4'h1:sm_seg_r = 8'h06;     //显示1   
         4'h2:sm_seg_r = 8'h5b;     //显示2   
         4'h3:sm_seg_r = 8'h4f;     //显示3   
         4'h4:sm_seg_r = 8'h66;     //显示4   
         4'h5:sm_seg_r = 8'h6d;     //显示5   
         4'h6:sm_seg_r = 8'h7d;     //显示6   
         4'h7:sm_seg_r = 8'h07;     //显示7   
         4'h8:sm_seg_r = 8'h7f;     //显示8   
         4'h9:sm_seg_r = 8'h6f;     //显示9   
         //4'ha:sm_seg_r = 8'hbf;     //显示-   
         default:sm_seg_r = 8'h00;    //不显示  
        endcase   
       end
//-----------------------------------------------------               
always@(en)
    if(!en)
      begin        //数码管显示倒计时时间设定
         green1<=8'b00100101;
         red1<=8'b00010000;
         yellow1<=8'd5;
         green2<=8'b00010000;
         red2<=8'b00100101;
         yellow2<=8'd5;
         
       end   
               
always@(posedge sec)//南北方向      
      begin   
         if(!rst)//复位模块   
            begin   
             light1<=3'b001;   
             num1<=green1;   
            end
         if(d1==1)
         begin
          light1<=3'b011;
         
          end
         else begin
         if(!tim1)     
          begin   
           tim1<=1;   
           case(state1)   
           2'd0:begin
                  
                                  num1<=green1;
                                  light1<=3'b011;
                                  state1<=2'd1;
               end
           2'd1:begin
               
                                  num1<=yellow1;
                                  light1<=3'b011;
                                  state1<=2'd2;
               end   
           2'd2:begin
                               
                                  num1<=red1;
                                  light1<=3'b110;
                                  state1<=2'd3;
                                end   
           2'd3:begin
                               
                                  num1<=yellow1;
                                  light1<=3'b101;
                                  state1<=2'd0;
                                end//状态机使三个状态一直循环
                       
           default:light1<=3'b011;   
          endcase   
          end     
         else     
           begin      
                                 if(num1==1) begin tim1<=0; num1 <= 0;end   
                                 else if(num1>0)   
                                 if(num1[3:0]==0)   
                                 begin   
                                 num1[3:0]<=4'b1001;//倒计时模块   
                                 num1[7:4]<=num1[7:4]-1;   
                                 end   
                                 else num1[3:0]<=num1[3:0]-1;           
            end   
            end      
            end
always@(posedge sec)//东西方向      
      begin   
              if(!rst)//复位模块     
              begin     
              light2<=3'b100;     
              num2<=red2;     
              end
              if(d1==1)
               begin
               light2<=3'b011;
               
               end
              else begin
              
              if(!tim2)      
              begin   
              tim2<=1;   
              case(state2)   
              2'd0:begin
                    
                     num2<=red2;
                     light2<=3'b110;
                     state2<=2'd1;
                    end   
             2'd1:begin
                    
                     num2<=yellow2;
                     light2<=3'b101;
                     state2<=2'd2;
                    end   
              2'd2:begin
                    
                      num2<=green2;
                      light2<=3'b011;
                      state2<=3'd3;
                    end   
              2'd3:begin
                    
                      num2<=yellow2;
                      light2<=3'b011;
                     state2<=2'd0;
                    end   
               
              default:light2<=3'b011;   
              endcase   
              end   
          else     
          begin      
             if(num2==1)begin tim2<=0;num2<=0;end   
             else if(num2>0)   
             if(num2[3:0]==0)   
             begin   
             num2[3:0]<=4'b1001;   
             num2[7:4]<=num2[7:4]-1;   
             end   
             else num2[3:0]<=num2[3:0]-1;           
          end   
          end end
     

//-----------------------------------------------------
         
reg key_rst;
     always @(posedge clk or negedge rst)
         if(!rst) key_rst<=1'b1;
         else key_rst<={sw1_n};
reg key_rst_r;
     always @(posedge clk or negedge rst)
        if(!rst) key_rst_r<=1'b1;
         else key_rst_r<=key_rst;
wire key_an=key_rst_r & (~key_rst);
        //  key_rst   111001
        //   ~key_rst   000110
         //  key_rst   111001
          // key_n       00100  
reg[19:0] cnt;
       always @(posedge clk or negedge rst)
          if(!rst) cnt<=20'd0;
          else if(key_an) cnt<=20'd0;
              else cnt<=cnt+1'b1;
reg low_sw;
       always @(posedge clk or negedge rst)
          if(!rst) low_sw<=1'b1;
          else if(cnt==20'hfffff)
          low_sw<=sw1_n;
reg low_sw_r;      
         always @(posedge clk or negedge rst)
          if(!rst) low_sw_r<=1'b0;
          else low_sw_r<=low_sw;
wire led_ctrl=low_sw_r&(~low_sw);
       reg d1;  
       always @(posedge clk or negedge rst)
     if(!rst)
         begin
         d1<=1'b0;
         end
     else
       begin
         if(led_ctrl)
           begin
             d1<=~d1;
           end
       end
endmodule

一周热门 更多>