Chia sẻ:
Notifications
Clear all

Phân biệt giữa blocking assignment (=) và non-blocking assignment (

2 Bài viết
2 Thành viên
0 Reactions
65 Lượt xem
(@admin)
Thành Viên Moderator
Tham gia: 6 năm trước
Bài viết: 27
Topic starter  

Phân biệt giữa blocking assignment (=)non-blocking assignment (<=) trong Verilog?


   
Trích dẫn
Thẻ chủ đề
(@Anonymous)
New Member Khách
Tham gia: 1 giây trước
Bài viết: 0
 

Trong Verilog, blocking assignment (=) và non-blocking assignment (<=) là hai cách gán giá trị cho các biến (đặc biệt là `reg` type) trong các khối `always`. Chúng có ảnh hưởng rất lớn đến cách mạch điện được mô phỏng và tổng hợp. Dưới đây là sự khác biệt chi tiết:

**1. Blocking Assignment (=)**

* **Hoạt động:** Blocking assignment thực hiện gán giá trị một cách **tuần tự** và **ngay lập tức**. Khi một dòng code chứa blocking assignment được thực thi, dòng code đó sẽ được hoàn thành trước khi trình mô phỏng (simulator) tiếp tục thực hiện các dòng code tiếp theo trong cùng một khối `always`.
* **Mô phỏng mạch điện:** Tương tự như các câu lệnh gán trong các ngôn ngữ lập trình thủ tục (ví dụ: C, Python). Giá trị của biến được cập nhật ngay lập tức và ảnh hưởng đến các phép tính tiếp theo trong cùng một khối `always`.
* **Ứng dụng:**
* **Mạch logic tổ hợp (combinational logic):** Thường được sử dụng để mô tả mạch logic tổ hợp vì đảm bảo rằng các phép tính được thực hiện theo đúng thứ tự mong muốn.
* **Các dòng code tuần tự bên trong một khối `always @(posedge clk)` (sequential logic):** Khi sử dụng blocking assignment **bên trong một khối `always` triggered bởi sườn xung clock (posedge clk)`, nó có thể được sử dụng để mô tả logic tuần tự một cách an toàn (mặc dù non-blocking assignment thường được khuyến khích).
* **Ví dụ:**

```verilog
always @(*) begin
a = b; // a được gán giá trị của b ngay lập tức
c = a; // c được gán giá trị mới của a (giá trị của b)
end
```

Trong ví dụ trên, nếu `b` thay đổi, `a` sẽ ngay lập tức nhận giá trị của `b`, và sau đó `c` sẽ nhận giá trị mới của `a`. Kết quả là `c` sẽ bằng `b`.

**2. Non-Blocking Assignment (<=)**

* **Hoạt động:** Non-blocking assignment thực hiện gán giá trị một cách **không tuần tự** và **trì hoãn**. Khi một dòng code chứa non-blocking assignment được thực thi, giá trị của biến sẽ được lên lịch để cập nhật vào **cuối chu kỳ mô phỏng hiện tại**. Các dòng code tiếp theo trong cùng một khối `always` sẽ được thực thi mà không cần chờ đợi việc gán giá trị hoàn tất.
* **Mô phỏng mạch điện:** Các non-blocking assignment có thể được xem như là tất cả các phép gán trong một khối `always` xảy ra đồng thời. Nó mô phỏng cách các flip-flop hoạt động trong thực tế, nơi tất cả các trạng thái được cập nhật đồng thời tại sườn xung clock.
* **Ứng dụng:**
* **Mạch logic tuần tự (sequential logic):** **Được sử dụng rộng rãi và được khuyến nghị** để mô tả mạch logic tuần tự (ví dụ: flip-flop, thanh ghi).
* **Tránh race condition:** Giúp tránh các race condition trong mô phỏng, đặc biệt là khi có nhiều khối `always` truy cập và cập nhật cùng một biến.
* **Ví dụ:**

```verilog
always @(posedge clk) begin
a <= b; // a sẽ nhận giá trị của b vào cuối chu kỳ clock
c <= a; // c sẽ nhận giá trị của a (giá trị của a ở đầu chu kỳ clock) vào cuối chu kỳ clock
end
```

Trong ví dụ trên, giả sử `b` thay đổi tại một thời điểm nào đó trong chu kỳ clock. `a` sẽ nhận giá trị mới của `b` vào **cuối chu kỳ clock**. Đồng thời, `c` sẽ nhận giá trị của `a` (tức là giá trị của `a` **ở đầu chu kỳ clock**, trước khi `a` được cập nhật) vào cuối chu kỳ clock. Do đó, `c` sẽ không bằng `b` trong chu kỳ clock đó. Giá trị của `c` sẽ chỉ bằng `b` sau một chu kỳ clock.

**Bảng so sánh tóm tắt:**

| Tính năng | Blocking Assignment (=) | Non-Blocking Assignment (<=) |
| -------------------- | ------------------------------- | -------------------------------- |
| Tính tuần tự | Tuần tự, thực hiện ngay lập tức | Không tuần tự, trì hoãn đến cuối chu kỳ |
| Mô phỏng mạch điện | Mô phỏng phép gán tuần tự | Mô phỏng phép gán đồng thời (flip-flop) |
| Ứng dụng chính | Mạch logic tổ hợp, logic tuần tự (cẩn thận) | Mạch logic tuần tự |
| Tránh race condition | Khó tránh | Dễ tránh |

**Quy tắc chung khi sử dụng:**

* **Logic tuần tự (Sequential Logic):** Sử dụng **non-blocking assignment (`<=`)** trong các khối `always @(posedge clk)` hoặc `always @(negedge clk)` để mô tả các flip-flop và thanh ghi.
* **Logic tổ hợp (Combinational Logic):** Sử dụng **blocking assignment (`=`)** trong các khối `always @(*)` hoặc `always @(sensitivity list)` để mô tả các mạch logic tổ hợp.
* **Đừng trộn lẫn:** **Không** trộn lẫn blocking và non-blocking assignment trong cùng một khối `always` nếu không có lý do chính đáng và hiểu rõ hậu quả. Điều này có thể dẫn đến kết quả mô phỏng không mong muốn và khó gỡ lỗi.
* **Assignments đến cùng một biến:** **Tránh** gán giá trị cho cùng một biến từ nhiều khối `always` khác nhau. Điều này có thể gây ra xung đột và kết quả không xác định. Thay vào đó, hãy sử dụng signal assignment (`assign`) cho logic tổ hợp hoặc thiết kế kiến trúc để tránh xung đột.

**Ví dụ sai:**

```verilog
always @(posedge clk) begin
a = b; // KHÔNG NÊN: Blocking assignment trong sequential logic
c <= a; // KHÔNG NÊN: Non-blocking assignment nhưng a đã bị gán giá trị bằng blocking assignment
end
```

Trong ví dụ trên, mặc dù `c` sử dụng non-blocking assignment, nhưng `a` lại được gán giá trị bằng blocking assignment. Điều này phá vỡ mô hình hoạt động của flip-flop và có thể dẫn đến kết quả không chính xác.

**Kết luận:**

Hiểu rõ sự khác biệt giữa blocking và non-blocking assignment là rất quan trọng để viết code Verilog chính xác và dễ bảo trì. Sử dụng đúng loại assignment trong từng trường hợp sẽ giúp bạn mô phỏng và tổng hợp mạch điện một cách chính xác và hiệu quả. Luôn tuân thủ các quy tắc chung để tránh các lỗi tiềm ẩn và đảm bảo mạch điện hoạt động như mong đợi.


   
Trả lờiTrích dẫn