下面是交通灯的设计代码,那位大哥帮看一下,仿真是有错误
控制模块:
module TR_ctl(clk,reset,m_req,b_req,cnt_ok,s_3s,s_20s,s_30s,mgreen,myellow,mred,bgreen,byellow,bred);
//模块端口说明
input clk;
input reset;
input m_req;
input b_req;
input cnt_ok;
output s_3s; reg s_3s;
output s_20s; reg s_20s;
output s_30s; reg s_30s;
output mgreen; reg mgreen;
output myellow; reg myellow;
output mred;reg mred;
output bgreen;reg bgreen;
output byellow; reg byellow;
output bred;reg bred;
// 变量说明
reg m_req_s0,b_req_s0,m_req_s,b_req_s;
reg [1:0] current_state,next_state;
// 参数说明
parameter S1=2'b00, S2='b01,//状态机编码
S3=2'b10, S4=2'b11;
// 输入同步电路
always @(negedge reset or posedge clk)
if (!reset) begin
m_req_s0<=0;
b_req_s0<=0;
m_req_s<=0;
b_req_s<=0;
end
else begin
m_req_s0<=~m_req;
b_req_s0<=~b_req;
m_req_s<=m_req_s0;
b_req_s<=b_req_s0;
end
//状态机组合逻辑
always @(cnt_ok or m_req_s or b_req_s or current_state)
begin
case(current_state)
S1: begin// 主干道绿,支干道红
mgreen<=0;myellow<=1; mred<=1;
bgreen<=1;byellow<=1; bred<=0;
s_3s<=0; s_20s<=0; s_30s<=0;
if( cnt_ok==1)// 计时时间到
if(b_req_s==0) begin//支干道有车.
s_3s<=1;
next_state<=S2;
end
else begin// 支干道无车.
s_30s<=1;
next_state<=S1;
end
else// 计时未到
next_state<=S1;
end
S2: begin //主干道黄,支干道红
mgreen<=1;myellow<=0; mred<=1;
bgreen<=1;byellow<=1; bred<=0;
s_3s<=0; s_20s<=0; s_30s<=0;
if(cnt_ok==1) begin// 计时时间到
s_20s<=1;
next_state<=S3;
end
else
next_state<=S2;
end
S3: begin // 支干道绿,主干道红
mgreen<=1;myellow<=1; mred<=0;
bgreen<=0;byellow<=1; bred<=1;
s_3s<=0; s_20s<=0; s_30s<=0;
if(cnt_ok==1)
// 支干道有车,主干道无车
if(b_req_s==0 && m_req_s==1) begin
s_20s<=1;
next_state<=S3;
end
else begin
s_3s<=1;
next_state<=S4;
end
else
next_state<=S3;
end
S4: begin// 支干道黄,主干道红
mgreen<=1;myellow<=1; mred<=0;
bgreen<=1;byellow<=0; bred<=1;
s_3s<=0; s_20s<=0; s_30s<=0;
if(cnt_ok==1) begin
s_30s<=1;
next_state<=S1;
end
else
next_state<=S4;
end
endcase
end
//状态机状态转移逻辑
always @(negedge reset or posedge clk)
if (!reset)
current_state<=S1;
else
current_state<=next_state;
endmodule
计数模块:
module clock_cnt
(clk,reset,s_3s,s_20s,s_30s,cnt_ok,d_time);
input clk;
input reset;
input s_3s;
input s_20s;
input s_30s;
output cnt_ok;
output [6:0] d_time;
//变量说明
reg [25:0] cnt_clk;
reg [2:0] cnt_10;
reg [3:0] cnt_1;
reg second_en;
//秒脉冲发生器
always @(negedge reset or posedge clk)
if ( !reset ) begin
cnt_clk<=26'd0;
second_en<=0;
end
else if( cnt_clk!=26'd40_000_000 ) begin //分频26'd40_000_000
cnt_clk<=cnt_clk+26'd1;
second_en<=0;
end
else begin
cnt_clk<=26'd0;
second_en<=1;
end
// {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!
// 初值可控的十进制减法计数器
always @(negedge reset or posedge clk)
if ( !reset )begin
cnt_10<=3'd0;
cnt_1<=4'd1;
end
else if(second_en==1)begin
if(s_3s) begin
cnt_10<=0;
cnt_1<=3; end
else if(s_20s) begin
cnt_10<=2;
cnt_1<=0;end
else if(s_30s) begin
cnt_10<=3;
cnt_1<=0;end
else if( cnt_1==0) begin
cnt_10<=cnt_10-3'd1;
cnt_1<=9;end
else
cnt_1<=cnt_1-3'd1;end
assign cnt_ok = (cnt_10==0&&cnt_1==1)? second_en : 1'b0;// 计时到信号
assign d_time = {cnt_10,cnt_1};//计数输出
endmodule
显示模块:
module disp_ctl (clk, reset, d_time, d_col, d_out);
// 端口说明
input clk;
input reset;
input [6:0] d_time;
output [1:0] d_col; reg [1:0] d_col;
output [7:0] d_out; reg [7:0] d_out;
//变量说明
reg [18:0] cnt_disp;
wire [3:0] LED_data;
//LED动态显示控制
always @(negedge reset or posedge clk)
if ( !reset ) begin
cnt_disp<=19'd0;
d_col<=2'b01;
end
else if( cnt_disp!=19'd400_000 )//显示延时19'd400_000
cnt_disp<=cnt_disp+1;
else begin
cnt_disp<=19'd0;
d_col<=~d_col;
end
//LED显示数据选择
assign LED_data = (d_col==2'b01)? {1'b0,d_time[6:4]}:d_time[3:0];
//LED显示译码逻辑
always@(LED_data)
begin
case(LED_data)
4'b0000: d_out=8'b0000_0011;
4'b0001: d_out=8'b1001_1111;
4'b0010: d_out=8'b0010_0101;
4'b0011: d_out=8'b0000_1101;
4'b0100: d_out=8'b1001_1001;
4'b0101: d_out=8'b0100_1001;
4'b0110: d_out=8'b0100_0001;
4'b0111: d_out=8'b0001_1111;
4'b1000: d_out=8'b0000_0001;
default:d_out=8'b0001_1001;
endcase
end
endmodule |