代码如下:
/*
模拟十字路口交
通信号灯的工作过程,设计要求如下:
(1)交通灯从绿变红时,有4s黄灯亮的间隔时间;
(2)交通灯从红变绿是直接进行的,没有间隔时间;
(3)主干道的绿灯时间为20s,支干道的绿灯时间为10s;
(4)每个状态要求有倒计时显示;
*/
module TRAFFIC(
//----------------------
//--输入端口
CLK_50M,RST_N,
//----------------------
//--输出端口
SGSEL,
SG,
LED,
);
//-----------------------
//--外部端口声明
input CLK_50M,RST_N;
output [2:0] SGSEL; //数码管位选信号,前两个显示主路倒计时,后两个显示支路倒计时
output [6:0] SG; //数码管段选信号
output [7:0] LED; //8个LED灯,前3个表示主路的红黄绿,后3个表示支路的红黄绿
reg [2:0] SGSEL_n;
reg [6:0] SG_n;
reg [2:0] SGSEL;
reg [6:0] SG;
reg [7:0] LED;
//------------------------
//--内部端口声明
reg [6:0] SG_n0,SG_n1,SG_n2,SG_n3,SG_n4,SG_n5,SG_n6,SG_n7;
reg [25:0] cnt_
time_1s,cnt_time_1s_n; //脉冲计数值
reg [3:0] state,next_state; //交通灯现态和次态
reg [13:0] cnt_time_2ms,cnt_time_2ms_n; //2ms计数值
reg [2:0] cnt_SGSEL,cnt_SGSEL_n; //计数扫描
//------------------------
//--参数定义
parameter IDLE = 4'b0000, S0 = 4'b0001, S1 = 4'b0010, S2 = 4'b0100, S3 = 4'b1000;
//--S0指主绿支红,S1指主黄支红,S2指主红支绿,S3指主红支黄
parameter Num_zero = 7'b1111_110,Num_one = 7'b0110_000,
Num_three = 7'b1111_001,Num_four = 7'b0110_011,
Num_five = 7'b1011_011,Num_six = 7'b1011_111,
Num_seven = 7'b1110_000,Num_eight = 7'b1111_111,
Num_nine = 7'b1111_011,Num_two = 7'b1101_101;
//------------------------
//--1s计数器
always @(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N) begin
cnt_time_1s <= 26'd0;
end
else begin
cnt_time_1s <= cnt_time_1s_n;
end
end
always @(*)
begin
if(cnt_time_1s == 26'd50_000_000) begin
cnt_time_1s_n = 26'd0;
end
else begin
cnt_time_1s_n = cnt_time_1s+1;
end
end
//-------------------------
//倒计时的计算
reg [4:0] time_down,time_down_n; //倒计时
reg [4:0] time_max; //时间上限
//倒计时
always @(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N) begin
time_down <= 5'd0;
end
else begin
time_down <= time_down_n;
end
end
always @(*)
begin
if(cnt_time_1s == 26'd50_000_000) begin
time_down_n = time_down-1;
end
else if(time_down == 5'd0) begin
time_down_n = time_max;
end
else begin
time_down_n = time_down;
end
end
//-------------------------
//--状态机的编写
//状态转换
always @(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N) begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
//下一状态的计算
always @(*)
begin
case(state)
IDLE: begin
time_max = 5'd20;
next_state = S0;
end
S0: begin
time_max = 5'd4;
if(time_down == 5'd0) begin
next_state = S1;
end
else begin
next_state = S0;
end
end
S1: begin
time_max = 5'd10;
if(time_down == 5'd0) begin
next_state = S2;
end
else begin
next_state = S1;
end
end
S2: begin
time_max = 5'd4;
if(time_down == 5'd0) begin
next_state = S3;
end
else begin
next_state = S2;
end
end
S3: begin
time_max = 5'd20;
if(time_down == 5'd0) begin
next_state = S0;
end
else begin
next_state = S3;
end
end
default: begin time_max = 5'bxxxxx; next_state = 4'bxxxx; end
endcase
end
//输出逻辑的处理
always @(*)
begin
case(state)
IDLE: LED = 8'b0000_0000;
S0: LED = 8'b0010_0100;
S1: LED = 8'b0100_0100;
S2: LED = 8'b1000_0001;
S3: LED = 8'b1000_0010;
default: LED = 8'b0000_0000;
endcase
end
//------------------------------
//--数码管显示倒计时
//每2ms扫描一次数码管
//2ms计数器
always @(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N) begin
cnt_time_2ms <= 14'd0;
end
else begin
cnt_time_2ms <= cnt_time_2ms_n;
end
end
always @(*)
begin
if(cnt_time_2ms == 14'd10_000) begin
cnt_time_2ms_n = 14'd0;
end
else begin
cnt_time_2ms_n = cnt_time_2ms+1;
end
end
always @(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N) begin
cnt_SGSEL <= 3'd0;
end
else begin
cnt_SGSEL <= cnt_SGSEL_n;
end
end
always @(*)
begin
if(cnt_time_2ms == 14'd10_000) begin
cnt_SGSEL_n = cnt_SGSEL+1;
end
else begin
cnt_SGSEL_n = cnt_SGSEL;
end
end
//数码管扫描译码
always @(*)
begin
case(cnt_SGSEL)
3'd0: begin SGSEL = 3'b000; SG = SG_n0; end
3'd1: begin SGSEL = 3'b001; SG = SG_n1; end
3'd2: begin SGSEL = 3'b010; SG = 7'd0; end
3'd3: begin SGSEL = 3'b011; SG = 7'd0; end
3'd4: begin SGSEL = 3'b100; SG = 7'd0; end
3'd5: begin SGSEL = 3'b101; SG = 7'd0; end
3'd6: begin SGSEL = 3'b110; SG = SG_n6; end
3'd7: begin SGSEL = 3'b111; SG = SG_n7; end
default: begin SGSEL = 3'bxxx; SG = 7'bxxxx_xxx; end
endcase
end
always @(*)
begin
case(time_down)
5'd0: begin SG_n0 = Num_zero; SG_n1 = Num_zero;
SG_n6 = Num_zero; SG_n7 = Num_zero;
end
5'd1: begin SG_n0 = Num_one; SG_n1 = Num_zero;
SG_n6 = Num_one; SG_n7 = Num_zero;
end
5'd2: begin SG_n0 = Num_two; SG_n1 = Num_zero;
SG_n6 = Num_two; SG_n7 = Num_zero;
end
5'd3: begin SG_n0 = Num_three; SG_n1 = Num_zero;
SG_n6 = Num_three; SG_n7 = Num_zero;
end
5'd4: begin SG_n0 = Num_four; SG_n1 = Num_zero;
SG_n6 = Num_four; SG_n7 = Num_zero;
end
5'd5: begin SG_n0 = Num_five; SG_n1 = Num_zero;
SG_n6 = Num_five; SG_n7 = Num_zero;
end
5'd6: begin SG_n0 = Num_six; SG_n1 = Num_zero;
SG_n6 = Num_six; SG_n7 = Num_zero;
end
5'd7: begin SG_n0 = Num_seven; SG_n1 = Num_zero;
SG_n6 = Num_seven; SG_n7 = Num_zero;
end
5'd8: begin SG_n0 = Num_eight; SG_n1 = Num_zero;
SG_n6 = Num_eight; SG_n7 = Num_zero;
end
5'd9: begin SG_n0 = Num_nine; SG_n1 = Num_zero;
SG_n6 = Num_nine; SG_n7 = Num_zero;
end
5'd10: begin SG_n0 = Num_zero; SG_n1 = Num_one;
SG_n6 = Num_zero; SG_n7 = Num_one;
end
5'd11: begin SG_n0 = Num_one; SG_n1 = Num_one;
SG_n6 = Num_one; SG_n7 = Num_one;
end
5'd12: begin SG_n0 = Num_two; SG_n1 = Num_one;
SG_n6 = Num_two; SG_n7 = Num_one;
end
5'd13: begin SG_n0 = Num_three; SG_n1 = Num_one;
SG_n6 = Num_three; SG_n7 = Num_one;
end
5'd14: begin SG_n0 = Num_four; SG_n1 = Num_one;
SG_n6 = Num_four; SG_n7 = Num_one;
end
5'd15: begin SG_n0 = Num_five; SG_n1 = Num_one;
SG_n6 = Num_five; SG_n7 = Num_one;
end
5'd16: begin SG_n0 = Num_six; SG_n1 = Num_one;
SG_n6 = Num_six; SG_n7 = Num_one;
end
5'd17: begin SG_n0 = Num_seven; SG_n1 = Num_one;
SG_n6 = Num_seven; SG_n7 = Num_one;
end
5'd18: begin SG_n0 = Num_eight; SG_n1 = Num_one;
SG_n6 = Num_eight; SG_n7 = Num_one;
end
5'd19: begin SG_n0 = Num_nine; SG_n1 = Num_one;
SG_n6 = Num_nine; SG_n7 = Num_one;
end
5'd20: begin SG_n0 = Num_zero; SG_n1 = Num_two;
SG_n6 = Num_zero; SG_n7 = Num_two;
end
default: begin SG_n0 = 7'd0; SG_n1 = 7'd0;
SG_n6 = 7'd0; SG_n7 = 7'd0;
end
endcase
end
endmodule
-
-
虽然不知道原因,但LED接地已经消失。至于LED[6]和小数点莫名其妙地亮了,发现是板子的设计问题。
非常感谢你的回答~
一周热门 更多>