以下是一个可能的实现:

module traffic_light_controller(
    input clk,     // 时钟信号
    input reset,   // 复位信号
    output reg [2:0] east_west,   // 东西方向灯控制信号
    output reg [2:0] north_south, // 南北方向灯控制信号
    output reg [3:0] countdown    // 倒计时数码管显示值
);

// 状态定义
localparam [2:0] WAIT_EW_GREEN = 3'b001;  // 等待东西方向绿灯
localparam [2:0] EW_GREEN = 3'b010;       // 东西方向绿灯
localparam [2:0] EW_YELLOW = 3'b011;      // 东西方向黄灯
localparam [2:0] WAIT_NS_RED = 3'b100;    // 等待南北方向红灯
localparam [2:0] NS_RED = 3'b101;         // 南北方向红灯
localparam [2:0] NS_GREEN = 3'b110;       // 南北方向绿灯
localparam [2:0] NS_YELLOW = 3'b111;      // 南北方向黄灯

// 状态寄存器和状态计数器
reg [2:0] state;
reg [3:0] state_counter;

// 灯持续时间计数器
reg [3:0] ew_green_counter;
reg [3:0] ew_yellow_counter;
reg [3:0] ns_red_counter;
reg [3:0] ns_green_counter;
reg [3:0] ns_yellow_counter;

// 倒计时计数器
reg [3:0] countdown_counter;

// 初始化状态和计数器
initial begin
    state = WAIT_EW_GREEN;
    state_counter = 0;
    ew_green_counter = 0;
    ew_yellow_counter = 0;
    ns_red_counter = 0;
    ns_green_counter = 0;
    ns_yellow_counter = 0;
    countdown_counter = 0;
end

// 状态转换和动作
always @(posedge clk) begin
    if (reset) begin
        state <= WAIT_EW_GREEN;
        state_counter <= 0;
        ew_green_counter <= 0;
        ew_yellow_counter <= 0;
        ns_red_counter <= 0;
        ns_green_counter <= 0;
        ns_yellow_counter <= 0;
        countdown_counter <= 0;
    end else begin
        // 状态计数器自增
        if (state_counter < 7) begin
            state_counter <= state_counter + 1;
        end else begin
            state_counter <= 0;
        end
        
        // 灯持续时间计数器自增
        case (state)
            WAIT_EW_GREEN: begin
                ew_green_counter <= ew_green_counter + 1;
            end
            EW_GREEN: begin
                ew_green_counter <= ew_green_counter + 1;
            end
            EW_YELLOW: begin
                ew_yellow_counter <= ew_yellow_counter + 1;
            end
            WAIT_NS_RED: begin
                ns_red_counter <= ns_red_counter + 1;
            end
            NS_RED: begin
                ns_red_counter <= ns_red_counter + 1;
            end
            NS_GREEN: begin
                ns_green_counter <= ns_green_counter + 1;
            end
            NS_YELLOW: begin
                ns_yellow_counter <= ns_yellow_counter + 1;
            end
        endcase
        
        // 倒计时计数器自减
        if (countdown_counter > 0) begin
            countdown_counter <= countdown_counter - 1;
        end
        
        // 状态转换
        case (state)
            WAIT_EW_GREEN: begin
                if (state_counter == 5) begin
                    state <= EW_GREEN;
                    countdown_counter <= 5;
                end
            end
            EW_GREEN: begin
                if (ew_green_counter == 5) begin
                    state <= EW_YELLOW;
                    countdown_counter <= 3;
                end
            end
            EW_YELLOW: begin
                if (ew_yellow_counter == 3) begin
                    state <= WAIT_NS_RED;
                    countdown_counter <= 8;
                end
            end
            WAIT_NS_RED: begin
                if (state_counter == 8) begin
                    state <= NS_RED;
                    countdown_counter <= 8;
                end
            end
            NS_RED: begin
                if (ns_red_counter == 8) begin
                    state <= NS_GREEN;
                    countdown_counter <= 5;
                end
            end
            NS_GREEN: begin
                if (ns_green_counter == 5) begin
                    state <= NS_YELLOW;
                    countdown_counter <= 3;
                end
            end
            NS_YELLOW: begin
                if (ns_yellow_counter == 3) begin
                    state <= WAIT_EW_GREEN;
                    countdown_counter <= 8;
                end
            end
        endcase
        
        // 灯控制信号
        case (state)
            WAIT_EW_GREEN: begin
                east_west <= 3'b010;   // 绿灯
                north_south <= 3'b101; // 红灯
            end
            EW_GREEN: begin
                east_west <= 3'b010;   // 绿灯
                north_south <= 3'b101; // 红灯
            end
            EW_YELLOW: begin
                east_west <= 3'b001;   // 黄灯
                north_south <= 3'b101; // 红灯
            end
            WAIT_NS_RED: begin
                east_west <= 3'b001;   // 黄灯
                north_south <= 3'b100; // 红灯
            end
            NS_RED: begin
                east_west <= 3'b001;   // 黄灯
                north_south <= 3'b100; // 红灯
            end
            NS_GREEN: begin
                east_west <= 3'b101;   // 红灯
                north_south <= 3'b010; // 绿灯
            end
            NS_YELLOW: begin
                east_west <= 3'b101;   // 红灯
                north_south <= 3'b001; // 黄灯
            end
        endcase
        
        // 倒计时数码管显示值
        if (countdown_counter == 5) begin
            countdown <= 3'b101; // 绿灯持续时间
        end else if (countdown_counter == 3) begin
            countdown <= 3'b011; // 黄灯持续时间
        end else if (countdown_counter == 0) begin
            countdown <= 3'b110; // 红灯持续时间
        end else begin
            countdown <= 4'b1111; // 显示“-”
        end
    end
end

endmodule

这个模块接收一个时钟信号和一个复位信号,输出两个方向上各自的灯控制信号和一个倒计时数码管显示值。它使用状态机来控制交通灯的切换,并且在每个状态下自动计算倒计时数码管的显示值。请注意,这个实现中的计数器和状态转换都是使用非阻塞赋值语句进行的,以确保状态转换的正确性。

Verilog 交通灯控制器设计:十字路口信号灯控制与倒计时显示

原文地址: https://www.cveoy.top/t/topic/lxzE 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录