Menu
CoddyTech

Khối always

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 46 trên 90.

Khối lệnh tuần tự là một khối code trong đó các câu lệnh chạy lần lượt theo thứ tự, giống như trong các ngôn ngữ lập trình như C hoặc Python. Verilog có hai khối lệnh tuần tự: initial (chạy một lần) và always (chạy liên tục). Hãy bắt đầu với khối always.

Khối always chạy liên tục. Khối này lặp lại mãi mãi sau khi mô phỏng bắt đầu. Khối này dùng để mô tả phần cứng cần hoạt động liên tục, chẳng hạn như flip-flop, bộ đếm và logic tổ hợp.

Cú pháp cơ bản:

always @(sensitivity_list) begin
  // Đoạn code chạy lặp lại
end

@(sensitivity_list) cho khối lệnh biết khi nào cần thực thi. Nếu không có nó (và không có độ trễ như #5 bên trong), khối lệnh sẽ lặp vô hạn và làm mô phỏng bị treo.

Ví dụ về khối always: bộ đếm

Đây là ví dụ về cách dùng khối always để tạo bộ đếm.

module counter (
  input clk,
  output reg [3:0] count
);
  always @(posedge clk) count <= count + 1;
endmodule

Cách hoạt động của đoạn code này

PhầnÝ nghĩa
alwaysChạy đoạn code này liên tục, mãi mãi
@(posedge clk)Chờ xung đồng hồ chuyển từ 0 lên 1 (cạnh lên)
count <= count + 1Lấy giá trị hiện tại của count, cộng thêm 1 rồi lưu lại

Khối lệnh chạy ở mỗi cạnh lên của xung nhịp. Mỗi lần, count tăng thêm 1.

Danh sách độ nhạy @(posedge clk) yêu cầu khối lệnh chỉ chạy tại các cạnh xung nhịp, không chạy liên tục. Nếu thiếu phần này, vòng lặp sẽ chạy mãi mà không có độ trễ.

Khối always với nhiều tín hiệu

Bạn có thể liệt kê các tín hiệu cụ thể:

always @(a or b) begin
  out = a & b;
end

Đoạn này chạy khi a hoặc b thay đổi.

challenge icon

Thử thách

Thêm khối always còn thiếu để module này hoạt động.

Cách hoạt động:

  • Ở mỗi cạnh lên của xung nhịp, out1 đảo trạng thái từ 0 sang 1 hoặc từ 1 sang 0
  • out2 làm theo out1 (có cùng giá trị với out1)

Cần làm:

  1. Thêm khối always @(posedge clk)
  2. Bên trong, cho out1 đảo trạng thái (dùng out1 = ~out1)
  3. Cho out2 bằng out1

Tự làm thử

module toggler (
  input clk,
  output reg out1,
  output reg out2
);

  initial begin
    out1 = 0;
    out2 = 0;
  end

  // TODO: Thêm khối lệnh always với posedge clk
  // out1 đảo trạng thái ở mỗi xung nhịp
  // out2 theo trạng thái của out1

endmodule
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

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