1系统总体设计

把由5OM的有源晶振产生的现场可编程逻辑器件FPGA 的系统时钟输入到分频模块,经分频模块分频产生频率为1Hz的时钟脉冲,作为控制定时模块、控制模块、紧急模块、计数模块的时钟信号,然后再由定时模块来控制紧急模块和控制模块,按照交通管理规则控制交通工作状态的切换,最后,由系统时钟和计数模块以及控制模块来共同控制计数器控制模块,计数器的时钟为lHz,再把计数器控制模块送出的BCD码送给译码器译码后,送给数码管显示各方向直行绿灯的倒计时。

图2.1.1

由系统开发需求,我们可以大致规划出系统的控制流程:交通灯控制模块将需要显示的时间数据连接到数码管显示模块,同时将状态信号连接到数码管控制模块,然后数码管显示模块和数码管控制模块驱动交通信号灯外设工作。系统框图如图2.1.1所示。

在分析如下需求状态后,可以得出:

状态1:主干道方向绿灯29s,支路红灯,

状态2:主干道方向黄灯3s, 支路红灯,

状态3:主干道左转方向绿灯14s,支路红灯,

状态4:主干道方向黄灯3s, 支路红灯,

状态5:支路方向绿灯20s,主干道红灯,

状态6:支路方向黄灯3s, 主干道红灯,

救援车紧急通行状态

状态7:主干道和支路都是红灯10s,之后恢复状态1循环进行。

特殊状态1:道路特殊情况时,主干道和支路都是黄灯,数码管为00,不改变。

特殊状态2:夜间黄灯闪烁。

2. 十字路口红绿灯功能设计

功能说明:该十字路口交通灯控制器用于主干道与支道公路的交叉路口,要求是优先保证主干道的畅通,因此,设计要求如下:

设计一个用于十字路口的交通灯控制器,能显示十字路口东西、南北两个方向的红、黄、绿的指示状态;

1.具有倒计时的功能,用两组数码管作为东西和南北方向的倒计时显示,主干道直行(绿灯)29秒后,左转(绿灯)14秒;支干道直行(绿灯)20秒,在每次绿灯变成红灯的转换过程中,要亮黄灯3秒作为过渡。

2.只考虑直行和左转车辆控制信号灯,右转车辆不受信号灯控制,南北向车辆与东西向车辆交替方向,同方向等待车辆应先方向直行车辆而后放行左转车辆。

3.救援车紧急通行模块是方便救护车和消防车快速通行,所以主干道和支路都为红灯。

3.主控制器模块原理上是一个状态机,依据要求设计,设计出信号灯点亮规律的状态转换表,其中0表示灭,1表示亮,状态表显示了信号灯在运行过程中每个状态应该持续的时间,以及状态之间的转换顺序。依据分频计数器,当分频计数器的时钟达到了对应时间则切换为下一个状态,就可以实现控制信号灯的亮灭。

本次设计较复杂,如果不采用状态机的方式实现起来会非常繁琐,所以在功能中采用状态机的方式实现。

状态1:主干道方向绿灯29s,支路红灯,

状态2:主干道方向黄灯3s, 支路红灯,

状态3:主干道左转方向绿灯14s,支路红灯,

状态4:主干道方向黄灯3s, 支路红灯,

状态5:支路方向绿灯20s,主干道红灯,

状态6:支路方向黄灯3s, 主干道红灯,

然后又重新进行状态1循环进行

救援车紧急通行模块

状态7:主干道和支路都是红灯10s,之后恢复状态1循环进行。

3.分频代码

module clk_div(
        input clk,
        input clr,
        output reg clk_out);
        
parameter FREQ=1000;
localparam NUM=50000000/(2*FREQ);
reg[29:0] count;
always@(posedge clk,negedge clr)
begin
    if(!clr) begin clk_out<=0;count<=0;end
    else if(count==NUM-1)
        begin count<=0;clk_out<=~clk_out;end
        else begin count<=count+1;end
end
endmodule

4.红绿灯

module color_led(
        input[3:0] led,
        output reg green,red,yellow,zuo);

always @(*)
begin
        case(led)
            4'b1000:   begin green<=1;yellow<=0;red<=0;zuo<=0;end
            4'b0100:   begin green<=0;yellow<=1;red<=0;zuo<=0;end
            4'b0010:   begin green<=0;yellow<=0;red<=1;zuo<=0;end
            4'b0011:   begin green<=0;yellow<=0;red<=1;zuo<=1;end
            default:   begin green<=1;yellow<=0;red<=0;zuo<=0;end
        endcase
end
endmodule        

5.数码管

module seg_led(

input [3:0] code_ge,code_shi,

output reg[6:0] led_ge,led_shi);

parameter D0=7’b1000000,D1=7’b1111001,D2=7’b0100100,D3=7’b0110000,D4=7’b0011001,

D5=7’b0010010,D6=7’b0000010,D7=7’b1111000,D8=7’b0000000,D9=7’b0010000;

always @(*)

begin

case(code_ge)

4’d0: led_ge = D0;

4’d1: led_ge = D1;

4’d2: led_ge = D2;

4’d3: led_ge = D3;

4’d4: led_ge = D4;

4’d5: led_ge = D5;

4’d6: led_ge = D6;

4’d7: led_ge = D7;

4’d8: led_ge = D8;

4’d9: led_ge = D9;

default: led_ge = 7’bx;

endcase

case(code_shi)

4’d0: led_shi = D0;

4’d1: led_shi = D1;

4’d2: led_shi = D2;

4’d3: led_shi = D3;

4’d4: led_shi = D4;

4’d5: led_shi = D5;

4’d6: led_shi = D6;

4’d7: led_shi = D7;

4’d8: led_shi = D8;

4’d9: led_shi = D9;

default: led_shi = 7’bx;

endcase

end

endmodule

6主模块

module top_traffic(
            input    clk,clr,
            output green,yellow,red,zuo,GREEN,YELLOW,RED,ZUO,
            output[6:0] led_ge,led_shi,LED_GE,LED_SHI);
    
wire clk1hz,clk2hz;
     
clk_div #(25000000) clk1(
                      .clk(clk),
                      .clr(clr),
                      .clk_out(clk1hz)
                      );

clk_div #(2) clk2(
                      .clk(clk),
                      .clr(clr),
                      .clk_out(clk2hz)
                      );

traffic_light light1(
                    .clk1hz(clk1hz),
                    .clr(clr),
                    .led_ge(led_ge),
                    .led_shi(led_shi),
                    .green(green),
                    .yellow(yellow),
                    .red(red),
                    .LED_GE(LED_GE),
                    .LED_SHI(LED_SHI),
                    .GREEN(GREEN),
                    .YELLOW(YELLOW),
                    .RED(RED),
                    .zuo(zuo),
                    .ZUO(ZUO)
                    );

endmodule


module traffic_light(
            input clk1hz,clr,
            output green,yellow,red,GREEN,YELLOW,RED,zuo,ZUO,
            output[6:0] led_ge,led_shi,LED_GE,LED_SHI);

reg[2:0]  color,COLOR;
reg[3:0]  state;
reg[3:0]  num_ge,num_shi,NUM_GE,NUM_SHI;
wire[3:0] ge,shi,GE,SHI;
wire[3:0] led,LED;

parameter S0=0,S1=1,S2=2,S3=3,S4=4,S5=5,G1=10;

always @(posedge clk1hz,negedge clr)
    
begin
    if(!clr) begin state<=S0;num_ge<=9;num_shi<=2;NUM_GE<=3;NUM_SHI<=3;end
    
    else begin
        case(state)
            S0:begin
                    num_ge<=num_ge-1;NUM_GE<=NUM_GE-1;
                    if(num_ge==0) begin num_ge<=9;num_shi<=num_shi-1;end
                    if(num_ge==0 && num_shi==0) begin num_ge<=3;num_shi<=0;state<=S1;end
                    if(NUM_GE==0) begin NUM_GE<=9;NUM_SHI<=NUM_SHI-1;end
                end
            S1:begin
                    num_ge<=num_ge-1;NUM_GE<=NUM_GE-1;    
                    if(num_ge==0 && num_shi==0) begin num_ge<=4;num_shi<=1;end
                    if(NUM_GE==0 && NUM_SHI==0) begin NUM_GE<=0;NUM_SHI<=1;state<=S2;end
                end
            S2:begin 
                    num_ge<=num_ge-1;NUM_GE<=NUM_GE-1;
                    if(num_ge==0) begin num_ge<=9;num_shi<=num_shi-1;end
                    if(NUM_GE==0) begin NUM_GE<=9;NUM_SHI<=NUM_SHI-1;end
                    if(NUM_GE==0 && NUM_SHI==0) begin NUM_GE<=3;NUM_SHI<=0;state<=S3;end
                end
            
            S3:begin
                    num_ge<=num_ge-1;NUM_GE<=NUM_GE-1;    
                    if(num_ge==0 && num_shi==0) begin num_ge<=4;num_shi<=2;end
                    if(NUM_GE==0 && NUM_SHI==0) begin NUM_GE<=0;NUM_SHI<=2;state<=S4;end
                end
            
          S4:begin 
                    num_ge<=num_ge-1;NUM_GE<=NUM_GE-1;
                    if(num_ge==0) begin num_ge<=9;num_shi<=num_shi-1;end
                    if(NUM_GE==0) begin NUM_GE<=9;NUM_SHI<=NUM_SHI-1;end
                    if(NUM_GE==0 && NUM_SHI==0) begin NUM_GE<=3;NUM_SHI<=0;state<=S5;end
                end
            S5:begin
                    num_ge<=num_ge-1;NUM_GE<=NUM_GE-1;    
                    if(num_ge==0 && num_shi==0) begin num_ge<=9;num_shi<=2;end
                    if(NUM_GE==0 && NUM_SHI==0) begin NUM_GE<=3;NUM_SHI<=3;state<=S0;end
                end
            G1:begin
                    num_ge<=num_ge;num_shi<=num_shi;NUM_GE<=NUM_GE-1;NUM_GE<=NUM_SHI;    
                end
            default:begin state<=S0;num_ge<=9;num_shi<=2;NUM_GE<=3;NUM_SHI<=3;end
        endcase end
end

always @(state)
    
begin
    case(state)
        S0:       begin color<=4'b1000;COLOR<=4'b0010;end
        S1:       begin color<=4'b0100;COLOR<=4'b0010;end
        S2:       begin color<=4'b0011;COLOR<=4'b0010;end
        S3:       begin color<=4'b0100;COLOR<=4'b0010;end
        S4:       begin color<=4'b0010;COLOR<=4'b1000;end
        S5:       begin color<=4'b0010;COLOR<=4'b0100;end
        default:  begin color<=4'b1000;COLOR<=4'b0010;end
    endcase 
end

assign led=color;
assign LED=COLOR;
assign ge=num_ge;
assign shi=num_shi;
assign GE=NUM_GE;
assign SHI=NUM_SHI;

color_led color_led1(
            .led(led),
            .green(green),
            .yellow(yellow),
            .red(red),
            .zuo(zuo)
            );    

seg_led seg_led1(
            .code_ge(ge),
            .code_shi(shi),
            .led_ge(led_ge),
            .led_shi(led_shi)
            );

color_led color_led2(
            .led(LED),
            .green(GREEN),
            .yellow(YELLOW),
            .red(RED),
            .zuo(ZUO)
            );    

seg_led seg_led2(
            .code_ge(GE),
            .code_shi(SHI),
            .led_ge(LED_GE),
            .led_shi(LED_SHI)
            );

            
endmodule

说明:该部分为实现红绿灯,左转功能的变化,主要利用了减法器原理,初始主干道方向绿灯29s,支路红灯,然后黄灯闪烁,当数码管为00时状态跳到S1,主干道左转绿灯赋值14s,然后是支路赋值20Ss依次循环,

救援车紧急通行模块

always @(posedge clk1hz,negedge rst_n,negedge M,negedge N,negedge shan)

begin

if(!M)begin state<=S6;dig_zhulu_m1<=9;dig_zhulu_m2<=0;Dig_zhilu_n1<=9;Dig_zhilu_n2<=0;end

S6:begin dig_zhulu_m1<=dig_zhulu_m1-1;Dig_zhilu_n1<=Dig_zhilu_n1-1;

if(dig_zhulu_m1==0 && dig_zhulu_m2==0) begin dig_zhulu_m1<=9;dig_zhulu_m2<=2;end

if(Dig_zhilu_n1==0 && Dig_zhilu_n2==0) begin Dig_zhilu_n1<=3;Dig_zhilu_n2<=3;state<=S0;end end

S6: begin light_zhulu<=4’b0010;

Light_zhilu<=4’b0010;end

说明:代码段为M判断按钮状态,当按下M按钮时执行代码段状态机S6,主干道和支路都变为红灯,倒计时10s后恢复为状态1.

3 十字路口红绿灯,左转,救援车紧急通行模块

1、功能测试设计的测试与分析

我主要是测试红绿黄灯,左转能否正常亮和跳转下一个状态,所以我先给clk和复位信号初值为0,然后经过#10单位时间后复位为1,交通灯开始工作,#10000时间按下按键M后进入救援车紧急通行模块。

clk=0;

rst_n=0;

#10 rst_n=1;

#10 M=1;

#10 N=1;

#10 shan=1;

//#10 M=0;

#10000 M=0;

#10010 M=1;

#10520 rst_n=0;

#10530 rst_n=1;

#11000 N=0;

#11010 N=1;

#11050 shan=0;

#11060 shan=1;

// –> end

$display(“Running testbench”);

end

always #10 clk=~clk;

2、modelsim仿真和分析

仿真结果和分析

分析:开始主干道直行(绿灯)29秒后,亮红灯,之后左转(绿灯)14秒变为3s黄灯;支干道直行(绿灯)20秒,在每次绿灯变成红灯的转换过程中,要亮黄灯3秒作为过渡。仿真结果正确

转自:
https://blog.csdn.net/m0_60473755/article/details/129595520