|
本帖最后由 fpgaw 于 2010-11-23 17:35 编辑
基于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));
light light( .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 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?我要注册
x
|