Menu
CoddyTech

Căn thời gian chuyển trạng thái

Thuộc phần Kiến thức nền tảng trong hành trình Verilog của Coddy. Bài học 81 trên 90.

challenge icon

Thử thách

Trong bài học này, bạn sẽ thêm logic bộ đếm để điều khiển thời gian mỗi đèn bật. Bộ đếm đếm ngược từ một giá trị được đặt trước về 0, rồi kích hoạt lần chuyển trạng thái tiếp theo.

Yêu cầu về thời gian

Trạng tháiThời lượngGiá trị bộ đếm
Xanh lá30 giây30
Vàng10 giây10
Đỏ40 giây40

Cách bộ đếm hoạt động

  1. Khi một trạng thái bắt đầu, bộ đếm được nạp giá trị thời lượng
  2. Sau mỗi nhịp đồng hồ, bộ đếm giảm đi 1
  3. Khi bộ đếm về 0, đã đến lúc chuyển sang trạng thái tiếp theo

Nhiệm vụ của bạn là thêm logic bộ đếm còn thiếu vào máy trạng thái. Đầu vào next từ bước trước không còn được dùng nữa: giờ đây bộ đếm quyết định thời điểm trạng thái thay đổi, và testbench không còn điều khiển next.

Cần làm:

  1. Xóa input next, khỏi phần khai báo module và thay điều kiện else if (next) bằng logic bộ đếm bên dưới
  2. Thêm khai báo reg [5:0] counter (giữ lại nếu bạn đã khai báo ở bước đầu tiên)
  3. Khi reset, đặt counter thành 0
  4. Khi counter == 0:
    • Nạp thời lượng của trạng thái tiếp theo vào bộ đếm
    • Chuyển sang trạng thái tiếp theo
  5. Nếu không, giảm bộ đếm đi 1 sau mỗi nhịp đồng hồ

Tự làm thử

module traffic_light (
  input clk,
  input reset,
  output reg red,
  output reg yellow,
  output reg green
);

  reg [1:0] state;
  // TODO: Khai báo thanh ghi counter (6 bit)
  

  // Gán giá trị cho đầu ra
  always @(*) begin
    case (state)
      0: begin green = 1; yellow = 0; red = 0; end
      1: begin green = 0; yellow = 1; red = 0; end
      2: begin green = 0; yellow = 0; red = 1; end
      default: begin green = 0; yellow = 0; red = 1; end
    endcase
  end

  // Máy trạng thái có định thời
  always @(posedge clk or posedge reset) begin
    if (reset) begin
      state <= 2;      // Bắt đầu ở đèn đỏ
      // TODO: Đặt counter về 0
      
    end else begin
      if (counter == 0) begin
        case (state)
          0: begin
            state <= 1;
            // TODO: Nạp giá trị vào counter cho đèn vàng (10 giây)
            
          end
          1: begin
            state <= 2;
            // TODO: Nạp giá trị vào counter cho đèn đỏ (40 giây)
            
          end
          2: begin
            state <= 0;
            // TODO: Nạp giá trị vào counter cho đèn xanh (30 giây)
            
          end
        endcase
      end else begin
        // TODO: Giảm counter đi 1
        
      end
    end
  end

endmodule

Tất cả bài học trong Kiến thức nền tảng

Tự luyện tập: Trình biên dịch Verilog online