Verilog实现十字路口交通灯控制器 - 带倒计时显示
以下是一个简单的十字路口交通灯控制器的Verilog代码,它包含两个方向的红绿灯,并使用数码管以倒计时的方式显示当前方向的剩余通行时间。
module traffic_light(
input clk, // 时钟信号
input reset, // 复位信号
output reg [3:0] east_west, // 东西方向灯控制信号
output reg [3:0] north_south, // 南北方向灯控制信号
output reg [3:0] countdown // 倒计时显示信号
);
// 定义状态
localparam [2:0] IDLE = 3'b000, // 空闲状态
EW_GREEN = 3'b001, // 东西方向绿灯状态
EW_YELLOW = 3'b010, // 东西方向黄灯状态
NS_GREEN = 3'b011, // 南北方向绿灯状态
NS_YELLOW = 3'b100; // 南北方向黄灯状态
// 定义计数器计数范围
localparam COUNT_MAX = 50000000; // 时钟频率为50MHz,计数50e6次为1s
// 定义状态寄存器
reg [2:0] state_reg, state_next;
// 定义计数器
reg [25:0] count_reg; // 25位的计数器可以计数50e6次,即1s
// 定义倒计时计数器
reg [3:0] countdown_reg;
// 状态转移逻辑
always @ (posedge clk or negedge reset) begin
if (reset == 0) begin
state_reg <= IDLE;
count_reg <= 0;
countdown_reg <= 5; // 初始为绿灯持续时间
end
else begin
state_reg <= state_next;
count_reg <= count_reg + 1;
if (countdown_reg > 0) begin
countdown_reg <= countdown_reg - 1;
end
end
end
// 状态机逻辑
always @ (*) begin
state_next = state_reg;
case (state_reg)
IDLE: begin
east_west <= 4'b0010; // 东西方向绿灯
north_south <= 4'b1000; // 南北方向红灯
countdown <= countdown_reg;
if (count_reg >= COUNT_MAX * 8) begin // 红灯持续8s
state_next = NS_GREEN;
count_reg <= 0;
countdown_reg <= 5; // 切换到南北方向绿灯,倒计时为绿灯持续时间
end
end
EW_GREEN: begin
east_west <= 4'b0010; // 东西方向绿灯
north_south <= 4'b1000; // 南北方向红灯
countdown <= countdown_reg;
if (count_reg >= COUNT_MAX * 5) begin // 绿灯持续5s
state_next = EW_YELLOW;
count_reg <= 0;
countdown_reg <= 3; // 切换到黄灯,倒计时为黄灯持续时间
end
end
EW_YELLOW: begin
east_west <= 4'b0100; // 东西方向黄灯
north_south <= 4'b1000; // 南北方向红灯
countdown <= countdown_reg;
if (count_reg >= COUNT_MAX * 3) begin // 黄灯持续3s
state_next = NS_GREEN;
count_reg <= 0;
countdown_reg <= 5; // 切换到南北方向绿灯,倒计时为绿灯持续时间
end
end
NS_GREEN: begin
east_west <= 4'b0001; // 东西方向红灯
north_south <= 4'b0100; // 南北方向绿灯
countdown <= countdown_reg;
if (count_reg >= COUNT_MAX * 8) begin // 红灯持续8s
state_next = NS_YELLOW;
count_reg <= 0;
countdown_reg <= 5; // 切换到东西方向绿灯,倒计时为绿灯持续时间
end
end
NS_YELLOW: begin
east_west <= 4'b0001; // 东西方向红灯
north_south <= 4'b0010; // 南北方向黄灯
countdown <= countdown_reg;
if (count_reg >= COUNT_MAX * 3) begin // 黄灯持续3s
state_next = EW_GREEN;
count_reg <= 0;
countdown_reg <= 5; // 切换到东西方向绿灯,倒计时为绿灯持续时间
end
end
endcase
end
endmodule
在这个代码中,我们使用了一个有限状态机来控制交通灯的状态。状态机有5种状态:空闲状态(IDLE)、东西方向绿灯状态(EW_GREEN)、东西方向黄灯状态(EW_YELLOW)、南北方向绿灯状态(NS_GREEN)和南北方向黄灯状态(NS_YELLOW)。我们使用一个状态寄存器(state_reg)来存储当前状态,使用一个状态转移逻辑来根据当前状态和计数器(count_reg)的值计算下一个状态(state_next)。我们还使用一个计数器来计算时间,以及一个倒计时计数器(countdown_reg)来计算当前状态下还剩多长时间。
在状态机逻辑中,我们根据当前状态来设置交通灯控制信号(east_west和north_south),并根据计数器(count_reg)的值来判断何时需要切换状态。同时,我们还将当前状态下的倒计时计数器(countdown_reg)的值作为倒计时显示信号(countdown)输出。
在模块实例化时,我们需要将时钟信号和复位信号连接到模块的输入端口上。同时,我们需要将交通灯控制信号(east_west和north_south)和倒计时显示信号(countdown)连接到模块的输出端口上,以便在测试时观察信号的变化。
原文地址: https://www.cveoy.top/t/topic/lxzD 著作权归作者所有。请勿转载和采集!