(笔记)(原创)一个小交通灯的Verilog描写
(笔记)(原创)一个小交通灯的Verilog描写
题记:有接近三个周都在写文档,两个文档同时写,事情太多了,也就有三个周没有碰过Verilog了,正好今天上机实现,刘老师让做一个交通灯,虽然说过去写过,但是那是在学习不深入的情况下 ,使用if_else乱飞的情况下写的。今天在上机一个多小时重新设计出一个简单的交通灯。modelsim中仿真没有问题,ISE中综合过也没有问题。望大家看了多多指教。
设计源代码:
module cortrol
(//input
rclk,rst_n,
part,
//output
pm,
sc
);
input rclk,rst_n;
input part;
output [4:0] pm,sc;
parameter ps_rg = 4'b0001,
ps_ry = 4'b0010,
ps_gr = 4'b0100,
ps_yr = 4'b1000;
parameter red_max =5'd29,
green_max = 5'd24,
yellow_max = 5'd4;
parameter fen_wide = 2;
parameter fen_max = 2'd2;
//================================
//
reg clk;
reg [fen_wide-1:0] fen_counter;
always @(posedge rclk or negedge rst_n)
begin
if(!rst_n)
begin
fen_counter <= 0;
clk <= 1'b0;
end
else if(fen_counter==fen_max)
begin
fen_counter <= 0;
clk <= ~clk;
end
else
fen_counter <= fen_counter + 1'b1;
end
//=============================================
//
//=============================================
reg [3:0] state,next_state;
reg pm_set_n,sc_set_n;
always @(state or pm or sc or part)
begin
pm_set_n = 1'b1;
sc_set_n = 1'b1;
next_state = state;
case(state)
ps_rg:
if(sc==5'd0)
begin
next_state = ps_ry;
sc_set_n = 1'b0;
end
ps_ry:
if(sc==5'd0)
begin
next_state = ps_gr;
sc_set_n = 1'b0;
pm_set_n = 1'b0;
end
ps_gr:
if(pm==5'd0)
begin
next_state = ps_yr;
pm_set_n = 1'b0;
end
ps_yr:
if(pm==5'd0)
begin
next_state = ps_rg;
sc_set_n = 1'b0;
pm_set_n = 1'b0;
end
endcase
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
state <= ps_rg;
else
state <= next_state;
end
//======================================
//
//======================================
reg [4:0] pm,sc;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
pm <= red_max;
sc <= green_max;
end
else if(!part)
begin
pm <= pm;
sc <= sc;
end
else
case(state)
ps_rg:
begin
pm <= pm - 1'b1;
if(!sc_set_n)
sc <= yellow_max;
else
sc <= sc - 1'b1;
end
ps_ry:
begin
if(!sc_set_n)
sc <= red_max;
else
sc <= sc - 1'b1;
if(!pm_set_n)
pm <= green_max;
else
pm <= pm - 1'b1;
end
ps_gr:
begin
sc <= sc - 1'b1;
if(!pm_set_n)
pm <= yellow_max;
else
pm <= pm - 1'b1;
end
ps_yr:
begin
if(!sc_set_n)
sc <= green_max;
else
sc <= sc - 1'b1;
if(!pm_set_n)
pm <= red_max;
else
pm <= pm - 1'b1;
end
endcase
end
endmodule
(//input
rclk,rst_n,
part,
//output
pm,
sc
);
input rclk,rst_n;
input part;
output [4:0] pm,sc;
parameter ps_rg = 4'b0001,
ps_ry = 4'b0010,
ps_gr = 4'b0100,
ps_yr = 4'b1000;
parameter red_max =5'd29,
green_max = 5'd24,
yellow_max = 5'd4;
parameter fen_wide = 2;
parameter fen_max = 2'd2;
//================================
//
reg clk;
reg [fen_wide-1:0] fen_counter;
always @(posedge rclk or negedge rst_n)
begin
if(!rst_n)
begin
fen_counter <= 0;
clk <= 1'b0;
end
else if(fen_counter==fen_max)
begin
fen_counter <= 0;
clk <= ~clk;
end
else
fen_counter <= fen_counter + 1'b1;
end
//=============================================
//
//=============================================
reg [3:0] state,next_state;
reg pm_set_n,sc_set_n;
always @(state or pm or sc or part)
begin
pm_set_n = 1'b1;
sc_set_n = 1'b1;
next_state = state;
case(state)
ps_rg:
if(sc==5'd0)
begin
next_state = ps_ry;
sc_set_n = 1'b0;
end
ps_ry:
if(sc==5'd0)
begin
next_state = ps_gr;
sc_set_n = 1'b0;
pm_set_n = 1'b0;
end
ps_gr:
if(pm==5'd0)
begin
next_state = ps_yr;
pm_set_n = 1'b0;
end
ps_yr:
if(pm==5'd0)
begin
next_state = ps_rg;
sc_set_n = 1'b0;
pm_set_n = 1'b0;
end
endcase
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
state <= ps_rg;
else
state <= next_state;
end
//======================================
//
//======================================
reg [4:0] pm,sc;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
pm <= red_max;
sc <= green_max;
end
else if(!part)
begin
pm <= pm;
sc <= sc;
end
else
case(state)
ps_rg:
begin
pm <= pm - 1'b1;
if(!sc_set_n)
sc <= yellow_max;
else
sc <= sc - 1'b1;
end
ps_ry:
begin
if(!sc_set_n)
sc <= red_max;
else
sc <= sc - 1'b1;
if(!pm_set_n)
pm <= green_max;
else
pm <= pm - 1'b1;
end
ps_gr:
begin
sc <= sc - 1'b1;
if(!pm_set_n)
pm <= yellow_max;
else
pm <= pm - 1'b1;
end
ps_yr:
begin
if(!sc_set_n)
sc <= green_max;
else
sc <= sc - 1'b1;
if(!pm_set_n)
pm <= red_max;
else
pm <= pm - 1'b1;
end
endcase
end
endmodule
仿真代码:
module sim;
reg clk,rst_n,part;
wire [4:0] pm,sc;
cortrol U
(//input
.rclk(clk),.rst_n(rst_n),
.part(part),
//output
.pm(pm),
.sc(sc)
);
always #5 clk = ~clk;
initial
begin
$monitor ($time,"pm=%d,sc=%d",pm,sc);
clk = 0;
rst_n = 1;
part = 1;
#7 rst_n = 0;
#7 rst_n = 1;
#200 part = 0;
#5 part = 1;
#100 $stop;
end
reg clk,rst_n,part;
wire [4:0] pm,sc;
cortrol U
(//input
.rclk(clk),.rst_n(rst_n),
.part(part),
//output
.pm(pm),
.sc(sc)
);
always #5 clk = ~clk;
initial
begin
$monitor ($time,"pm=%d,sc=%d",pm,sc);
clk = 0;
rst_n = 1;
part = 1;
#7 rst_n = 0;
#7 rst_n = 1;
#200 part = 0;
#5 part = 1;
#100 $stop;
end
endmodule