功能代码:
module traffic(CLK,EN,LAMPA,LAMPB,ACOUNT,BCOUNT,Ra,Ga,Ya,LGa,Rb,Gb,Yb,LGb); //端口说明
output [7:0] ACOUNT,BCOUNT;
output Ra,Ga,Ya,LGa,Rb,Gb,Yb,LGb;
output [3:0] LAMPA,LAMPB;
input CLK,EN; //内部信号说明
reg [7:0] numa,numb; //ACOUNT和BCOUNT的内部信号
reg tempa,tempb;
reg [2:0]counta,countb; //方向A和方向B的灯的状态
reg [7:0]ared,ayellow,agreen,aleft,bred,byellow,bgreen,bleft;
reg [3:0]LAMPA,LAMPB;
//设置各交通灯的持续时间初始化值,红灯的值由另一个方向的黄灯和绿灯计算得出。
assign {Ra,Ya,Ga,LGa}=LAMPA;
assign {Rb,Yb,Gb,LGb}=LAMPB;
always @(EN)
if(!EN) begin //使能信号EN无效时,对交通灯的计数值进行初始化
ared <=8'd55; //55 s , 30 + 5 + 15 + 5
ayellow <=8'd5; //5 s
agreen <=8'd40; //40 s
aleft <=8'd15; //15 s
bred <=8'd65; //65 s , 40 + 5 + 15 + 5
byellow <=8'd5; //5 s
bleft <=8'd15; //15 s
bgreen <=8'd30; //30 s
LAMPA <=4'b1000; //初始化状态
LAMPB <=4'b1000;
numa <=4'b0; //初始化计数
numb <=4'b0;
end
assign ACOUNT=numa; //计数信号输出
assign BCOUNT=numb; //计数信号输出
//控制A方向4种灯的模块
always @(posedge CLK) begin
if(EN) begin //使能有效时,交通灯开始工作
if(!tempa) begin
tempa<=1;
case(counta) //控制灯状态的顺序
0: begin //状态0
numa<=agreen; //直行绿灯亮
LAMPA<=2; //输出0010
counta<=1; //进入下一个状态
end
1: begin //状态1
numa<=ayellow; //黄灯亮
LAMPA<=4; //输出0100
counta<=2; //进入下一个状态
end
2: begin //状态2
numa<=aleft; //左转绿灯亮
LAMPA<=1; //输出0001
counta<=3; //进入下一个状态
end
3: begin //状态3
numa<=ayellow; //黄灯亮
LAMPA<=4; //输出0100
counta<=4; //进入下一个状态
end
4: begin //状态4
numa<=ared; //红灯亮
LAMPA<=8; //输出1000
counta<=0; //进入下一个状态(状态0)
end
default: //默认状态
LAMPA<=8; //红灯亮,输出1000
endcase
end
else begin //每一个状态的倒计时
if(numa>1) //判断倒计时未归零时分别对高地位进行递减
numa <= numa-1'b1;
if (numa==2) //计时到1时结束计时
tempa<=0; //倒计时结束,返回灯状态变化判断,将进入下一个状态
end
end
else begin
LAMPA<=4'b1000; //使能无效时,红灯亮
counta<=0; //返回方向A的状态0(绿灯状态)
tempa<=0; //进入状态变化判断
end
end
//控制B方向4种灯的模块
always @(posedge CLK) begin
if (EN) begin
if(!tempb) begin
tempb<=1;
case (countb)
0: begin
numb<=bred;
LAMPB<=8;
countb<=1;
end
1: begin
numb<=bgreen;
LAMPB<=2;
countb<=2;
end
2: begin
numb<=byellow;
LAMPB<=4;
countb<=3;
end
3: begin
numb<=bleft;
LAMPB<=1;
countb<=4;
end
4: begin
numb<=byellow;
LAMPB<=4;
countb<=0;
end
default:
LAMPB<=8;
endcase
end
else begin //倒计时
if(numb>1)
numb <= numb-1'b1;
if(numb==2)
tempb<=0;
end
end
else begin
LAMPB<=4'b1000;
tempb<=0;
countb<=0;
end
end
endmodule
测试代码
`timescale 1ns/1ns
module traffic_tb;
//Input
reg clk;
reg en;
//Output
wire [3:0] lampa,lampb;
wire [7:0] acount,bcount;
wire Ra,Ga,Ya,LGa,Rb,Gb,Yb,LGb;
initial
begin
en = 1’b0;
clk = 0’b0;
#11 en = 1’b1;
end
always #1 clk <= ~clk;
traffic tf(
.CLK(clk),
.EN(en),
.LAMPA(lampa),
.LAMPB(lampb),
.ACOUNT(acount),
.BCOUNT(bcount),
.Ra(Ra),
.Ga(Ga),
.Ya(Ya),
.LGa(LGa),
.Rb(Rb),
.Gb(Gb),
.Yb(Yb),
.LGb(LGb)
);
endmodule