Verilog 交通灯控制器设计:十字路口信号灯控制与倒计时显示
首先,我们需要定义输入和输出端口:
module traffic_light_controller(
input clk,
input reset,
output reg [2:0] east_west, // 红绿黄 0 1 2
output reg [2:0] north_south, // 红绿黄 0 1 2
output reg [3:0] time // 显示剩余时间
);
接下来,我们定义一些常量:
parameter GREEN_TIME = 5;
parameter YELLOW_TIME = 3;
parameter RED_TIME = 8;
parameter EAST_WEST_GREEN = 1;
parameter EAST_WEST_YELLOW = 2;
parameter EAST_WEST_RED = 0;
parameter NORTH_SOUTH_GREEN = 2;
parameter NORTH_SOUTH_YELLOW = 1;
parameter NORTH_SOUTH_RED = 0;
接着,我们需要定义一些状态变量:
reg [2:0] east_west_state;
reg [2:0] north_south_state;
reg [3:0] east_west_time;
reg [3:0] north_south_time;
然后,我们需要写一个状态机来控制交通灯的状态:
always @(posedge clk, posedge reset) begin
if (reset) begin // 复位状态
east_west_state <= EAST_WEST_RED;
north_south_state <= NORTH_SOUTH_GREEN;
east_west_time <= GREEN_TIME;
north_south_time <= GREEN_TIME;
end else begin
case (east_west_state)
EAST_WEST_GREEN: begin // 东西方向绿灯
if (east_west_time > 0) begin
east_west_time <= east_west_time - 1;
end else begin
east_west_state <= EAST_WEST_YELLOW; // 绿灯结束,进入黄灯
east_west_time <= YELLOW_TIME;
end
end
EAST_WEST_YELLOW: begin // 东西方向黄灯
if (east_west_time > 0) begin
east_west_time <= east_west_time - 1;
end else begin
east_west_state <= EAST_WEST_RED; // 黄灯结束,进入红灯
east_west_time <= RED_TIME;
end
end
EAST_WEST_RED: begin // 东西方向红灯
if (east_west_time > 0) begin
east_west_time <= east_west_time - 1;
end else begin
east_west_state <= EAST_WEST_GREEN; // 红灯结束,进入绿灯
east_west_time <= GREEN_TIME;
end
end
endcase
case (north_south_state)
NORTH_SOUTH_GREEN: begin // 南北方向绿灯
if (north_south_time > 0) begin
north_south_time <= north_south_time - 1;
end else begin
north_south_state <= NORTH_SOUTH_YELLOW; // 绿灯结束,进入黄灯
north_south_time <= YELLOW_TIME;
end
end
NORTH_SOUTH_YELLOW: begin // 南北方向黄灯
if (north_south_time > 0) begin
north_south_time <= north_south_time - 1;
end else begin
north_south_state <= NORTH_SOUTH_RED; // 黄灯结束,进入红灯
north_south_time <= RED_TIME;
end
end
NORTH_SOUTH_RED: begin // 南北方向红灯
if (north_south_time > 0) begin
north_south_time <= north_south_time - 1;
end else begin
north_south_state <= NORTH_SOUTH_GREEN; // 红灯结束,进入绿灯
north_south_time <= GREEN_TIME;
end
end
endcase
end
end
最后,我们需要写一个模块来显示剩余时间:
always @(posedge clk) begin
if (east_west_state == EAST_WEST_GREEN) begin
time <= east_west_time;
end else if (east_west_state == EAST_WEST_YELLOW) begin
time <= east_west_time + GREEN_TIME;
end else if (east_west_state == EAST_WEST_RED) begin
time <= east_west_time + GREEN_TIME + YELLOW_TIME;
end else if (north_south_state == NORTH_SOUTH_GREEN) begin
time <= north_south_time;
end else if (north_south_state == NORTH_SOUTH_YELLOW) begin
time <= north_south_time + GREEN_TIME;
end else if (north_south_state == NORTH_SOUTH_RED) begin
time <= north_south_time + GREEN_TIME + YELLOW_TIME;
end
end
完整代码如下:
module traffic_light_controller(
input clk,
input reset,
output reg [2:0] east_west, // 红绿黄 0 1 2
output reg [2:0] north_south, // 红绿黄 0 1 2
output reg [3:0] time // 显示剩余时间
);
parameter GREEN_TIME = 5;
parameter YELLOW_TIME = 3;
parameter RED_TIME = 8;
parameter EAST_WEST_GREEN = 1;
parameter EAST_WEST_YELLOW = 2;
parameter EAST_WEST_RED = 0;
parameter NORTH_SOUTH_GREEN = 2;
parameter NORTH_SOUTH_YELLOW = 1;
parameter NORTH_SOUTH_RED = 0;
reg [2:0] east_west_state;
reg [2:0] north_south_state;
reg [3:0] east_west_time;
reg [3:0] north_south_time;
always @(posedge clk, posedge reset) begin
if (reset) begin // 复位状态
east_west_state <= EAST_WEST_RED;
north_south_state <= NORTH_SOUTH_GREEN;
east_west_time <= GREEN_TIME;
north_south_time <= GREEN_TIME;
end else begin
case (east_west_state)
EAST_WEST_GREEN: begin // 东西方向绿灯
if (east_west_time > 0) begin
east_west_time <= east_west_time - 1;
end else begin
east_west_state <= EAST_WEST_YELLOW; // 绿灯结束,进入黄灯
east_west_time <= YELLOW_TIME;
end
end
EAST_WEST_YELLOW: begin // 东西方向黄灯
if (east_west_time > 0) begin
east_west_time <= east_west_time - 1;
end else begin
east_west_state <= EAST_WEST_RED; // 黄灯结束,进入红灯
east_west_time <= RED_TIME;
end
end
EAST_WEST_RED: begin // 东西方向红灯
if (east_west_time > 0) begin
east_west_time <= east_west_time - 1;
end else begin
east_west_state <= EAST_WEST_GREEN; // 红灯结束,进入绿灯
east_west_time <= GREEN_TIME;
end
end
endcase
case (north_south_state)
NORTH_SOUTH_GREEN: begin // 南北方向绿灯
if (north_south_time > 0) begin
north_south_time <= north_south_time - 1;
end else begin
north_south_state <= NORTH_SOUTH_YELLOW; // 绿灯结束,进入黄灯
north_south_time <= YELLOW_TIME;
end
end
NORTH_SOUTH_YELLOW: begin // 南北方向黄灯
if (north_south_time > 0) begin
north_south_time <= north_south_time - 1;
end else begin
north_south_state <= NORTH_SOUTH_RED; // 黄灯结束,进入红灯
north_south_time <= RED_TIME;
end
end
NORTH_SOUTH_RED: begin // 南北方向红灯
if (north_south_time > 0) begin
north_south_time <= north_south_time - 1;
end else begin
north_south_state <= NORTH_SOUTH_GREEN; // 红灯结束,进入绿灯
north_south_time <= GREEN_TIME;
end
end
endcase
end
end
always @(posedge clk) begin
if (east_west_state == EAST_WEST_GREEN) begin
east_west <= {1'b0, 1'b1, 1'b0}; // 绿灯
time <= east_west_time;
end else if (east_west_state == EAST_WEST_YELLOW) begin
east_west <= {1'b0, 1'b0, 1'b1}; // 黄灯
time <= east_west_time + GREEN_TIME;
end else if (east_west_state == EAST_WEST_RED) begin
east_west <= {1'b1, 1'b0, 1'b0}; // 红灯
time <= east_west_time + GREEN_TIME + YELLOW_TIME;
end
if (north_south_state == NORTH_SOUTH_GREEN) begin
north_south <= {1'b0, 1'b1, 1'b0}; // 绿灯
time <= north_south_time;
end else if (north_south_state == NORTH_SOUTH_YELLOW) begin
north_south <= {1'b0, 1'b0, 1'b1}; // 黄灯
time <= north_south_time + GREEN_TIME;
end else if (north_south_state == NORTH_SOUTH_RED) begin
north_south <= {1'b1, 1'b0, 1'b0}; // 红灯
time <= north_south_time + GREEN_TIME + YELLOW_TIME;
end
end
endmodule
原文地址: https://www.cveoy.top/t/topic/lxzN 著作权归作者所有。请勿转载和采集!