你帮我看看,这个加了按键,按下的时候是红灯灯都亮,减计数停,但是再按一下按键那个灯不恢复正常状态
代码:module trafic_lambp(clk,sm_bit,sm_seg,en,rst,light1,light2,sw1_n);
input clk;//定义时钟引脚
input rst,en; //定义复位和使能引脚
input sw1_n;
output [3:0]sm_bit;//定义数码管位选引脚
output [7:0]sm_seg;//定义数码管段选引脚
output[2:0]light1,light2;//定义两个方向交通灯
reg [3:0]sm_bit_r;
reg [7:0]sm_seg_r;
reg [7:0]disp_dat;//定义数码管显示数据寄存器
reg[24:0]count;//定义计数器寄存器
reg sec;//定义秒信号寄存器
reg tim1,tim2;//定义tim1位倒计时是否到达的位标识
reg[1:0]state1,state2;//定义一些状态
reg[2:0]light1,light2;
reg[7:0]num1,num2;//num1和num2的值为倒计时的值
reg[7:0]red1,red2,green1,green2,yellow1,yellow2;//定义红黄蓝灯的一些状态
assign sm_bit=sm_bit_r;
assign sm_seg=sm_seg_r;
//-----------------------------------------------------
always@(posedge clk)
begin count=count+1'b1;
if(count==25'd12500000 )//产生1HZ的时钟信号
begin
count=25'd0;
sec=~sec;
end
end
//-----------------------------------------------------
always@(posedge clk)
begin
case (count[17:15])
3'd0:disp_dat = num1[3:0];//秒个位
3'd1:disp_dat = num1[7:4]; //秒十位
//3'd2:disp_dat = 4'ha; //显示"-"
3'd3:disp_dat = num2[3:0]; //分个位
3'd4:disp_dat = num2[7:4]; //分十位
//3'd5:disp_dat = 4'ha; //显示"-"
endcase
case(count[17:15]) //选择数码管显示位
3'd0:sm_bit_r = 4'b1110; //选择第一个数码管显示
3'd1:sm_bit_r = 4'b1101; //选择第二个数码管显示
//3'd2:sm_bit_r = 8'b11111011; //选择第三个数码管显示
3'd3:sm_bit_r = 4'b1011; //选择第四个数码管显示
3'd4:sm_bit_r = 4'b0111; //选择第五个数码管显示
//3'd5:sm_bit_r = 8'b11011111; //选择第六个数码管显示
//3'd6:sm_bit_r = 8'b10111111; //选择第七个数码管显示
//3'd7:sm_bit_r = 8'b01111111; //选择第八个数码管显示
endcase
end
//-----------------------------------------------------
always @(posedge clk)
begin
case(disp_dat)
4'h0:sm_seg_r = 8'h3f; //显示0
4'h1:sm_seg_r = 8'h06; //显示1
4'h2:sm_seg_r = 8'h5b; //显示2
4'h3:sm_seg_r = 8'h4f; //显示3
4'h4:sm_seg_r = 8'h66; //显示4
4'h5:sm_seg_r = 8'h6d; //显示5
4'h6:sm_seg_r = 8'h7d; //显示6
4'h7:sm_seg_r = 8'h07; //显示7
4'h8:sm_seg_r = 8'h7f; //显示8
4'h9:sm_seg_r = 8'h6f; //显示9
//4'ha:sm_seg_r = 8'hbf; //显示-
default:sm_seg_r = 8'h00; //不显示
endcase
end
//-----------------------------------------------------
always@(en)
if(!en)
begin //数码管显示倒计时时间设定
green1<=8'b00100101;
red1<=8'b00010000;
yellow1<=8'd5;
green2<=8'b00010000;
red2<=8'b00100101;
yellow2<=8'd5;
end
always@(posedge sec)//南北方向
begin
if(!rst)//复位模块
begin
light1<=3'b001;
num1<=green1;
end
if(d1==1)
begin
light1<=3'b011;
end
else begin
if(!tim1)
begin
tim1<=1;
case(state1)
2'd0:begin
num1<=green1;
light1<=3'b011;
state1<=2'd1;
end
2'd1:begin
num1<=yellow1;
light1<=3'b011;
state1<=2'd2;
end
2'd2:begin
num1<=red1;
light1<=3'b110;
state1<=2'd3;
end
2'd3:begin
num1<=yellow1;
light1<=3'b101;
state1<=2'd0;
end//状态机使三个状态一直循环
default:light1<=3'b011;
endcase
end
else
begin
if(num1==1) begin tim1<=0; num1 <= 0;end
else if(num1>0)
if(num1[3:0]==0)
begin
num1[3:0]<=4'b1001;//倒计时模块
num1[7:4]<=num1[7:4]-1;
end
else num1[3:0]<=num1[3:0]-1;
end
end
end
always@(posedge sec)//东西方向
begin
if(!rst)//复位模块
begin
light2<=3'b100;
num2<=red2;
end
if(d1==1)
begin
light2<=3'b011;
end
else begin
if(!tim2)
begin
tim2<=1;
case(state2)
2'd0:begin
num2<=red2;
light2<=3'b110;
state2<=2'd1;
end
2'd1:begin
num2<=yellow2;
light2<=3'b101;
state2<=2'd2;
end
2'd2:begin
num2<=green2;
light2<=3'b011;
state2<=3'd3;
end
2'd3:begin
num2<=yellow2;
light2<=3'b011;
state2<=2'd0;
end
default:light2<=3'b011;
endcase
end
else
begin
if(num2==1)begin tim2<=0;num2<=0;end
else if(num2>0)
if(num2[3:0]==0)
begin
num2[3:0]<=4'b1001;
num2[7:4]<=num2[7:4]-1;
end
else num2[3:0]<=num2[3:0]-1;
end
end end
//-----------------------------------------------------
reg key_rst;
always @(posedge clk or negedge rst)
if(!rst) key_rst<=1'b1;
else key_rst<={sw1_n};
reg key_rst_r;
always @(posedge clk or negedge rst)
if(!rst) key_rst_r<=1'b1;
else key_rst_r<=key_rst;
wire key_an=key_rst_r & (~key_rst);
// key_rst 111001
// ~key_rst 000110
// key_rst 111001
// key_n 00100
reg[19:0] cnt;
always @(posedge clk or negedge rst)
if(!rst) cnt<=20'd0;
else if(key_an) cnt<=20'd0;
else cnt<=cnt+1'b1;
reg low_sw;
always @(posedge clk or negedge rst)
if(!rst) low_sw<=1'b1;
else if(cnt==20'hfffff)
low_sw<=sw1_n;
reg low_sw_r;
always @(posedge clk or negedge rst)
if(!rst) low_sw_r<=1'b0;
else low_sw_r<=low_sw;
wire led_ctrl=low_sw_r&(~low_sw);
reg d1;
always @(posedge clk or negedge rst)
if(!rst)
begin
d1<=1'b0;
end
else
begin
if(led_ctrl)
begin
d1<=~d1;
end
end
endmodule |