Named event: notification, triggered state và các case tool chưa hỗ trợ

Khoảng 45 phútMức 2/3Bản nháp: một số khẳng định chưa đối chiếu spec

Sau bài này bạn sẽ

  • Phân biệt chờ một trigger tương lai với kiểm triggered trong time slot
  • Không nhầm notification với queue lưu message
  • Giữ ->>, event assignment và wait_order failures theo đúng scope

Thông báo đã xảy ra có được lưu lại cho người đến sau?

Một thread phát event rồi một thread khác mới tới điểm chờ. Nếu dùng @event sau trigger, nó chờ lần trigger tiếp theo; không có một message được lưu sẵn để lấy. Trong cùng time slot, wait(event.triggered) có thể nhận biết event đã được phát trước đó.

Hai cơ chế này phục vụ hai ý định khác nhau. Trước khi sửa một deadlock bằng thay @ thành wait, hãy xác định consumer muốn chờ một notification mới hay kiểm sự kiện của time slot hiện tại. Event không mang payload và không thay mailbox khi cần lưu dữ liệu/đếm các message chưa nhận.

Trigger -> và waiter đã đăng ký

Main đợi tới 2 ns rồi thực hiện ->pulse. Sau đó cùng process gọi wait(pulse.triggered) và phải đi tiếp ngay ở 2 ns. Nó không có @pulse đã đăng ký từ trước cho lần trigger đầu, nên dùng case này để phân biệt hai ý định chờ.

Pha tiếp tạo một child đợi @pulse trước và child khác trigger sau 1 ns. Waiter phải thức ở 3 ns. Delay dương bảo đảm điểm đăng ký đã có trước trigger này; main không giả định một thứ tự giữa hai process cùng bắt đầu chờ/phát ở cùng timestamp.

[1]

Triggered giữ theo time slot, không giữ mãi như cờ done

Sau trigger ở 3 ns, main chờ thêm 1 ns và kiểm pulse.triggered đã false ở 4 ns. Nó cũng kiểm thời gian từng pha và tổng ba oracle. Flag triggered giúp chờ trong cùng time slot; không có nghĩa một waiter đến ở bất kỳ lúc nào trong tương lai đều được đánh thức bởi trigger cũ.

Flag boolean không chứa sequence number hoặc số message. Một loop lặp wait(triggered) khi nó vẫn true có thể chạy nhiều lần mà không có trigger mới, thậm chí tạo vòng lặp không tiến thời gian. Main chỉ dùng một wait và có chuyển thời gian rõ ràng trước phép kiểm reset.

@event sau một trigger đã qua sẽ chờ lần sau

Fault thay wait(pulse.triggered) đầu tiên thành @pulse bị watchdog 10 ns bắt. Main chưa đi tới pha tạo trigger 3 ns vì đã kẹt ở điểm chờ đầu. Đây là một đồ thị phụ thuộc có deadlock, không phải simulator phải tự phát lại notification 2 ns.

Trong môi trường thật, hãy vẽ ai có thể tạo trigger tiếp theo và process đó có đang bị chặn phía sau cùng waiter hay không. Chỉ tăng timeout không tạo ra một producer bị thiếu. Nếu cần state bền qua time slot, dùng một state/sequence/message có ownership rõ thay vì trông đợi event lưu lịch sử.

->> có hợp đồng lập lịch khác, không tự sửa mọi kiểu đến muộn

Trong ngữ cảnh module của ví dụ training, ->> lên lịch notification ở nhóm NBA của cùng time slot. Điều đó có thể cho các waiter đăng ký ở Active trước notification. Nó không biến event thành queue và không hứa một waiter đến ở time slot sau nhận lại trigger cũ.

Probe tối giản phát ->>queued rồi @queued trong cùng initial với kỳ vọng tiếp tục cùng 2 ns. Trên tool hiện tại, probe parse được nhưng rơi vào watchdog 10 ns. Main chỉ dùng ->; không thay ->> bằng -> trong chính probe để đánh dấu nó đã đạt.

[2]

Wait_order không tương đương chỉ ghép hai @

Wait_order mô tả một danh sách event cần đúng thứ tự và có nhánh xử lý khi thứ tự sai. Chỉ viết @a rồi @b có thể bỏ qua b đã xảy ra sớm trước a, thay vì báo vi phạm ngay; nó không tự chứng minh cùng một hợp đồng kiểm thứ tự.

Probe first ở 1 ns, second ở 2 ns có nhánh success và oracle 2 ns. Verilator từ chối build với diagnostic Unsupported: wait_order dù pyslang chấp nhận. Bài giữ source/diagnostic, không dùng một implementation khác không bắt wrong-order để gọi construct gốc đã được mô phỏng.

Gán event liên quan binding của synchronization object

Một event variable có thể tham chiếu synchronization object; gán giữa các event không phải copy một hàng dữ liệu payload. Waiter đã gắn với object nào và biểu thức wait có phụ thuộc biến nào cần được phân tích khi đổi binding.

Probe gán alias_event=pulse trong module bị tool từ chối vì assignment to/from event trong statically scheduled context. Nó không chứng minh mọi dạng dynamic event assignment đều bất hợp lệ theo SV. Main không có alias assignment, nên PASS không bao phủ phần này; chi tiết waiter cũ sau đổi binding vẫn cần LRM/case tool riêng.

Ba oracle ở 2 ns,3 ns và 4 ns

Expected trước chạy: EVENT CHECK same_slot_ns=2 second_pulse_ns=3 reset_triggered=1 checks=3 time_ns=4. Main parsed/simulated với Verilator. Bỏ wait-triggered đúng hợp đồng hoặc đổi trigger thứ hai sang 4 ns đều bị checker bắt trong bản sao.

Named event: notification, triggered state và các case tool chưa hỗ trợ

Expected tính trước chạy: EVENT CHECK same_slot_ns=2 second_pulse_ns=3 reset_triggered=1 checks=3 time_ns=4

tb.sv testbench
`timescale 1ns/1ps// Expected blocking pulse at2ns; .triggered wait in same slot succeeds, next observer sees pulse3, flag reset4.module tb_events; event pulse; int checks=0,same_slot=-1,second_pulse=-1; initial begin  #2;->pulse;  wait(pulse.triggered);same_slot=int'($time);  if(same_slot!=2)$fatal(1,"event same-slot triggered oracle");checks++;  fork   begin @pulse;second_pulse=int'($time);end   begin #1;->pulse;end  join  if(second_pulse!=3||$time!=3)$fatal(1,"event registered-waiter oracle");checks++;  #1;  if(pulse.triggered||$time!=4)$fatal(1,"event triggered reset oracle");checks++;  $display("EVENT CHECK same_slot_ns=2 second_pulse_ns=3 reset_triggered=1 checks=3 time_ns=4");$finish; end initial begin #10;$fatal(1,"event watchdog");endendmodule

Đã kiểm chứng thế nào

  • Phân tích và elaborate theo LRM (pyslang 12.1.0)
  • Mô phỏng, exit 0 và output khớp kỳ vọng tính tay (Verilator 5.050, 2-state)

Output phải khớp: EVENT CHECK same_slot_ns=2 second_pulse_ns=3 reset_triggered=1 checks=3 time_ns=4

Main chỉ blockingtrigger, @waiter đăng ký trước và triggered/reset trong các slot 2/3/4 ns.

->>then@ watchdog; static event assignment vàwait_order buildfail giữ riêng. Không claim mọi event API hoặc mọi binding behavior.

Các kiểm tra chạy lúc xây dựng nội dung (2026-11-06), không chạy trong trình duyệt. Kỳ vọng được tính tay trước khi chạy.

Ba capability probes tách riêng: ->> rồi @ bị watchdog; event assignment ở staticmodule và wait_order bị build rejection. Không gọi chúng là ba main mô phỏng thành công, cũng không biến diagnostic tool thành quy tắc ngôn ngữ phổ quát.

[3]

Tự kiểm tra

Tự kiểm tra: events

  1. Sau ->pulse ở 2 ns, wait(pulse.triggered) của main tiếp tục lúc nào?
  2. Main kiểm triggered đã false ở thời điểm nào?
  3. Thay wait(triggered) đầu bằng @pulse ngay sau ->pulse sẽ ra sao trong case này?
  4. @a rồi @b có luôn tương đương wait_order(a,b) không?
  5. Ba capability probes lỗi có được tính là main simulatedPASS không?

Chọn notification hay state trước khi chọn cú pháp chờ

Xác định trigger đã xảy ra hay còn ở tương lai, waiter đăng ký lúc nào và điều kiện nào làm simulation tiến. Dùng triggered trong đúng time slot, dùng message/state cho dữ liệu cần bền. Khi một construct nâng cao chưa được tool hỗ trợ, giữ case nhỏ và failure thật thay vì đổi contract để lấy nhãn xanh.

Nguồn và mức độ đối chiếu

  1. SystemVerilog Event — bản chụp resources.zip, How to Trigger and Wait for an Event; What's the Difference Between @ and .triggered?. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. SystemVerilog Event — bản chụp resources.zip, Non-Blocking Trigger: ->>; wait_order: Enforcing a Specific Order; Merging Events. Trích dẫn; nguồn đã đọc các mục liên quan.
  3. Thí nghiệm nguyên bản ex.b7.events, Source, self-checks, verification.json và concurrency probes. Trích dẫn; nguồn đã đọc toàn văn.
  4. IEEE 1800-2023 SystemVerilog LRM, Processes, synchronization and IPC methods — chưa đối chiếu LRM. Chưa đối chiếu với văn bản nguồn (chưa mở).