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