特权同学

基于CPLD的十字路口交通灯设计

0
阅读(2092)

基于CPLD的十字路口交通灯设计

说明:

横向红灯纵向绿灯30秒;

横向红灯纵向黄灯5秒;

横向黄灯纵向红灯5秒;

横向绿灯纵向红灯50秒(假设横向的车流量大,所以通行时间长);

横向黄灯纵向红灯5秒;

横向红灯纵向黄灯5秒。

(循环上述步骤)。

 

       RTL视图:(四个模块一目了然)

  

       芯片:alter公司的MAX II 系列EPM240T100C5

 

Verilog代码:(由于特权同学的键盘前两天被折腾了,有部分字母按键失灵,所以写程序的时候是软硬键盘一起使,郁闷的直接连注释都省了。)

 

(顶层模块)

module traffic(clk,rst,row,light_v,led,ledseg);

 

       input clk;

       input rst;

       output[3:0] row;          // NWSE

       output[2:0] light_v;              //red,yellow,green

       output[5:0] led;

       output[7:0] ledseg;

      

       wire[2:0] light0_reg,light1_reg;

       wire second;

       wire clk_50k;

       wire[6:0] count;

      

       clk1000div           clk1000div(   .clk(clk),

                                                        .rst(rst),

                                                        .clk_50k(clk_50k));

      

       clkdiv     clkdiv(    .clk(clk),

                                   .rst(rst),

                                   .second(second));

                                  

       lightlight(       .rst(rst),

                                   .second(second),

                                   .light0_reg(light0_reg),

                                   .light1_reg(light1_reg),

                                   .count(count));

      

       light_dis  light_dis(.clk(clk_50k),

                                                 .rst(rst),

                                                 .count(count),

                                                 .light0_reg(light0_reg),

                                                 .light1_reg(light1_reg),

                                                 .row(row),

                                                 .light_v(light_v),

                                                 .led(led),

                                                 .ledseg(ledseg));

 

endmodule

 

 

       (该模块是1000分频产生50KHz信号,主要用于液晶或者交通灯的动态显示定时)

module clk1000div(clk,rst,clk_50k);

 

       input clk;

       input rst;

       output clk_50k;

 

       reg[9:0] div;

       reg clk_50k;

      

       always @ (posedge clk) begin

              if(!rst) begin

                     div <= 0;

                     clk_50k <= 0;

                     end

              else begin

                     if(div==999) begin

                            clk_50k <= ~clk_50k;

                            div <= 0; end

                     else begin

                         div <= div+1; end

                     end

       end

 

endmodule

 

 

(1Hz分频模块,用于交通灯的定时)

module clkdiv(clk,rst,second);

 

       input clk;

       input rst;

       output second;

      

       reg[27:0] num;

       reg second;

      

       always @ (posedge clk) begin

              if(!rst) begin

                     num <= 0;

                     second <= 0;

                     end

              else begin

                     num <= num+28'd1;

                     if(num==28'h2faf080) begin

                            second <= ~second;

                            num <= 0;

                            end

                     end

       end

 

endmodule

 

 

       (该模块主要用于计算倒计时数值和交通灯的排选)

module light(rst,second,light0_reg,light1_reg,count);

 

       input rst;

       input second;

       output[2:0] light0_reg,light1_reg;

       output[6:0] count;

      

       reg[6:0] count;

       reg[6:0] state;

       reg[2:0] light0_reg,light1_reg;

      

       always @ (posedge second) begin

              if(!rst) begin

                     state <= 0;

                     end

              else begin

                     if(state == 7'd99) begin

                            state <= 0;

                            end

                     else begin

                            state <= state+1; end

                            end

       end

      

       always @ (state) begin

                     if(state<30) begin

                            count <= 29-state;

                            light0_reg <= 3'b001;

                            light1_reg <= 3'b100;

                            end

                     if(state>29 && state<35) begin

                            count <= 34-state;

                            light0_reg <= 3'b010;

                            light1_reg <= 3'b100;

                            end

                     if(state>34 && state<40) begin

                            count <= 39-state;

                            light0_reg <= 3'b100;

                            light1_reg <= 3'b010;

                            end

                     if(state>39 && state<90) begin

                            count <= 89-state;

                            light0_reg <= 3'b100;

                            light1_reg <= 3'b001;

                            end

                     if(state>89 && state<95) begin

                            count <= 94-state;

                            light0_reg <= 3'b100;

                            light1_reg <= 3'b010;

                            end

                     if(state>94 && state<100) begin

                            count <= 99-state;

                            light0_reg <= 3'b010;

                            light1_reg <= 3'b100;

                            end

       end

 

endmodule

 

 

       (该模块进行数码管倒计时显示和交通灯显示控制)

module light_dis(clk,rst,count,light0_reg,light1_reg,row,light_v,led,ledseg);

 

       input clk;

       input rst;

       input[6:0] count;

       input[2:0] light0_reg,light1_reg;

       output[5:0] led;

       output[7:0] ledseg;

       output[3:0] row;            // NWSE

       output[2:0] light_v;        // red,yellow,green

      

       reg[3:0] row;         // NWSE

       reg[2:0] light_v;            // red,yellow,green

       reg state;

       reg[5:0] led;

       reg[7:0] ledseg;

       reg[7:0] ledreg[1:0];

       reg[7:0] led_shu[9:0];

      

       always @ (posedge clk) begin

              if(!rst) begin

                     state <= 0;

                     led_shu[0] <= 8'h3f;

                     led_shu[1] <= 8'h06;

                     led_shu[2] <= 8'h5b;

                     led_shu[3] <= 8'h4f;

                     led_shu[4] <= 8'h66;

                     led_shu[5] <= 8'h6d;

                     led_shu[6] <= 8'h7d;

                     led_shu[7] <= 8'h07;

                     led_shu[8] <= 8'h7f;

                     led_shu[9] <= 8'h6f;

                     end

              else begin

                     state <= state+1;

                     if(count<10) begin

                            ledreg[0] <= led_shu[count];

                            ledreg[1] <= led_shu[0];             

                            end

                     else if(count<20) begin

                            ledreg[0] <= led_shu[count-10];

                            ledreg[1] <= led_shu[1];

                            end

                     else if(count<30) begin

                            ledreg[0] <= led_shu[count-20];

                            ledreg[1] <= led_shu[2];

                            end

                     else if(count<40) begin

                            ledreg[0] <= led_shu[count-30];

                            ledreg[1] <= led_shu[3];

                            end

                     else begin

                            ledreg[0] <= led_shu[count-40];

                            ledreg[1] <= led_shu[4];

                            end

              end

       end

      

       always @ (state) begin

              case (state)

                     0: begin

                            row <= 4'b0101;

                            light_v <= light0_reg;                         

                            led <= 6'b111110;

                            ledseg <= ledreg[1];

                            end

                     1: begin                       

                            row <= 4'b1010;

                            light_v <= light1_reg;

                            led <= 6'b111101;

                            ledseg <= ledreg[0];                           

                            end

                     default: ;

                     endcase

       end

 

endmodule