Thứ Sáu, 4 tháng 5, 2018

[System Verilog] Mô hình mô phỏng sự kiện – phần 3: Ví dụ cho Verilog


Tiếp theo bài: http://nguyenquanicd.blogspot.com/2018/05/system-verilog-cac-vung-mien-su-kien.html

Để làm rõ các khái niệm về sự thực thi mô phỏng theo mô hình sự kiện trong Verilog, lưu ý bài này chỉ phân tích trên mô hình thực thi mô phỏng của Verilog 2005, chúng ta sẽ phân tích ví dụ sau đây:
module evaluates2 (out);
  output out;
  reg a, b, c;
  initial begin    a = 0;
    b = 1;
    c = 0;
  end
  always c = #5 ~c;
  always @(posedge c) begin    a <= b; // evaluates, schedules,
    b <= a; // and executes in two steps
  end
endmodule 
Trong đoạn code ví dụ trên đây, khi thực thi mô phỏng, tại thời điểm bắt đầu T = 0, trình mô phỏng sinh ra 3 process tương ứng với 1 initial và 2 always. Tạm gọi là:
  • process initial
  • process always 1
  • process always 2
Các nhóm sự kiện tại thời điểm T = 0 như sau:
1/ Các sự kiện active gồm
  •   a = 0
  •   b = 1
  •   c = 0
Các sự kiện trên được xếp vào nhóm các sự kiện active của thời điểm hiện tại vì đây là các phép gán blocking và không có mô tả độ trễ. Các sự kiện này sẽ được đưa vào hàng đợi sự kiện để chờ thực thi.
2/ Các sự kiện inactive (không có tại thời điểm T = 0)
3/ Các sự kiện cập nhật phép gán nonblocking (không có tại thời điểm T = 0)
4/ Các sự kiện monitor (không có tại thời điểm T = 0)
5/ Các sự kiện tương lai (tại thời điểm T = 5) gồm
  • 1 sự kiện inactive tương lai (future inactive event): c = ~c
  • 2 sự kiện cập nhật phép gán nonblocking tương lai (future nonblocking assigment update event):
       a <= b
       b <= a

Trình tự thực thi của trình mô phỏng theo mô hình mô phỏng sự kiện của Verilog 2005 như sau:

1/ Thực thi các sự kiện active:
Theo lý thuyết các sự kiện active thuộc các process khác nhau có thể được thực thi theo bất kỳ thứ tự nào. Trong ví dụ này, vì các sự kiện active đều cùng thuộc 1 process nên sẽ thực thi theo thứ tự xuất hiện trong cặp begin-end. Cả 3 sự kiện này đều là các sự kiện cập nhật nên sẽ chạy theo nhánh của sự kiện cập nhật.
a = 0 và b = 1 sẽ được thi và cập nhật giá trị cho đối tượng được điều chỉnh là a và b. Do không có process nào khác chịu sự tác động của thay đổi này nên không có thêm các sự kiện ước lượng process được thêm vào hàng đợi sự kiện. Hai sự kiện này sẽ bị loại bỏ sau khi thực thi xong.
Hình 1: Quá trình xử lý hai sự kiện cập nhật a và b
c = 0 cũng chạy theo nhánh xử lý sự kiện cập nhật. Sau khi giá trị của c được gán, cũng không có sự kiện ước lượng process nào được thêm vào hàng đợi sự kiện, ở đây process always 2 chỉ chịu ảnh hưởng của sự kiện cạnh lên của c. Sự kiện c được loại bỏ khỏi hàng đợi sự kiện. Process initial cũng bị loại bỏ khi tất cả các sự kiện của nó đã hoàn thành.
Hình 2: Process initial chỉ tồn tại tại thời điểm T = 0
Trình mô phỏng tiếp tục kiểm tra còn tồn tại sự kiện nào hay không thì thấy còn các sự kiện tương lai tại thời điểm T = 5. Nó tiếp tục chạy qua nhánh này. Tăng T đến thời điểm 5, lúc này T = 5 trở thành thời điểm hiện tại, sự kiện c = ~c được chuyển thành sự kiện active và đây là một sự kiện cập nhật vì nó là phép gán blocking.
Hình 3: Quy trình xử lý sự kiện c = 0 và chuyển đến thời điểm T = 5
Sự kiện c = ~c sẽ làm cho c = 1 và làm xuất hiện cạnh lên của c. Theo nhánh xử lý sự kiện cập nhật, một sự kiện ước lượng của process always 2 sẽ được thêm vào hàng đợi sự kiện và sự kiện này sẽ được xử lý theo nhánh của sự kiện ước lượng.
Hình 4: Quy trình xử lý sự kiện cập nhật c = ~c và chuyển đến sự kiện ước lượng process always 2
Trong quá trình ước lượng process always 2, các giá trị vế bên phải của phép gán nonblocking trong process always 2 sẽ được ước lượng và gán giá trị như sau: 
  • b = 1 
  • a = 0
Chú ý, giá trị trên đây là giá trị ước lượng của vế bên phải phép gán nonblocking. Sau khi ước lượng xong, hai sự kiện cập nhật phép gán nonblocking được thêm vào hàng đợi sự kiện. Trình mô phỏng sẽ chạy qua nhánh xử lý sự kiện cập nhật phép gán nonblocking, kích hoạt tất cả các sự kiện này và chuyển đến nhánh xử lý sự kiện active. Vì a <= b và b <= a là sự kiện cập nhật nên nó sẽ đi vào nhánh xử lý sự kiện cập nhật.
Hình 5: Quy trình xử lý sự kiện ước lượng process always 2 và chuyển đến nhánh xử lý các sự kiện cập nhật phép gán nonblocking
Tại nhánh xử lý sự kiện cập nhật, thứ tự thực hiện là: 
  • a được gán bằng 1, không có process nào khác chịu tác động của sự thay đổi này nên không có sự kiện mới được thêm vào hàng đợi. 
  • Trình mô phỏng quay lại nhánh xử lý sự kiện cập nhật 1 lần nữa để gán b bằng 0, không có process nào khác chịu tác động của sự thay đổi này nên không có sự kiện mới được thêm vào hàng đợi.
Hình 6: Quá trình xử lý 2 sự kiện cập nhật phép gán nonblocking của a và b; chuyển đến thời điểm mô phỏng tiếp theo T = T + 5
Quá trình xử lý cho thời điểm T = 5 kết thúc, trình mô phỏng tăng đến thời điểm xử lý tiếp theo là T = 10. Quá trình xử lý c = ~c và process always 2 được lặp lại. Qua đây ta cũng thấy được đặc tính khác nhau của initial và always khi thực thi mô phỏng: 
  • initial chỉ thực thi một lần, các hoạt động của nó sẽ dừng khi các phát biểu của nó hoàn thành.
  • always được thực thi lặp lại, các hoạt động của nó chỉ dừng khi ngừng chạy mô phỏng.
Xét theo quá trình xử lý trên khái niệm khe thời gian (các bạn xem lại các phần trước để biết chi tiết) thì quá trình mô phỏng đoạn code ví dụ như hình minh họa sau đây:
Hình 7: Minh họa quá trình mô phỏng theo khe thời gian

0 bình luận:

Đăng nhận xét