Local variables trong SVA: giữ dữ liệu riêng cho các attempt chồng lấn
Tiên quyết
Sau bài này bạn sẽ
- Capture dữ liệu tại match và dùng lại ở deadline của chính attempt
- Phân biệt local storage với một thanh ghi dùng chung
- Chọn local variable hoặc history có độ sâu cố định theo bài toán
Giá trị mới nhất chưa chắc thuộc yêu cầu đang kiểm
Dữ liệu có thể thay đổi trước khi kết quả cần được kiểm. Nếu hai yêu cầu đang chờ, mỗi yêu cầu phải giữ giá trị của chính nó.
Giả sử lần đầu mang dữ liệu 3, lần sau mang 5. Khi kết quả của lần đầu về, đọc “giá trị mới nhất” sẽ lấy nhầm 5. Biến local trong property giúp gắn dữ liệu với attempt đang theo dõi.
Hai attempt chồng lấn giữ hai giá trị khác nhau
Xét yêu cầu phải được đáp ứng sau đúng hai tick. Hai cặp start liên tiếp tạo các nghĩa vụ sau:
| Tick start | Giá trị cần giữ | Deadline | Response sampled | Kết luận |
|---|---|---|---|---|
| 1 | 3 | 3 | valid=1, out=3 | Đúng |
| 2 | 5 | 4 | valid=1, out=5 | Đúng |
| 6 | 7 | 8 | valid=1, out=7 | Đúng |
| 7 | 9 | 9 | valid=1, out=8 | Vi phạm |
Khi attempt từ tick 2 đã giữ 5, attempt từ tick 1 vẫn cần 3. Response cuối cố ý sai để phân biệt kiểm nội dung với việc chỉ thấy out_valid là cho qua.
Assignment action gắn việc capture với một match
Property có thể khai báo bit [3:0] v;, rồi dùng (start, v=data) |-> ##2 (out_valid && out==v).
Dấu phẩy ở đây không tách ra một lệnh procedural chạy độc lập. Giá trị capture phải được dùng đúng trên đường match đã gán nó.
Khi start false, antecedent không match nên không tạo nghĩa vụ consequent cần v. Nếu bỏ implication, một sequence đứng riêng không tự có cùng cơ chế vacuity.
Vì sao biến dùng chung tạo báo động sai
Giả sử một biến module-level latest được cập nhật mỗi khi có start. Tới tick 3, latest đã bằng 5 từ yêu cầu tại tick 2; so response 3 với latest sẽ báo nhầm lỗi. Tới tick 8, tình huống tương tự xảy ra giữa dữ liệu 7 và 9.
Tick 9 lại có lỗi thật: response bằng 8 thay vì 9. Biến dùng chung vì thế vừa tạo báo động sai vừa khó chỉ ra nguồn dữ liệu của từng phép so.
Có một thanh ghi lưu giá trị gần nhất chưa có nghĩa đã có storage riêng cho mọi yêu cầu đang sống.
Khi history hai tick cũng trả đúng dữ liệu
Với độ trễ cố định hai tick và lịch sử hợp lệ, out == $past(data, 2) tại deadline cũng tìm đúng mẫu từ tick start.
Ở deadline tick 3, history hai tick trả data của tick 1 là 3. Hai attempt chồng lấn không tự làm cách dùng history cố định này sai.
Chọn local capture khi cần giữ giá trị gắn với một match cụ thể. Chọn history khi quan hệ số tick và điều kiện lịch sử hợp lệ đã rõ. Ví dụ này chưa giải quyết response đảo thứ tự, clock gating hoặc mọi độ trễ thay đổi.
Scope, kiểu dữ liệu và lúc giá trị hợp lệ
Biến v được khai báo trong property, còn latest nằm ở module. Đổi tên biến hoặc đưa nó vào một always block không tự tạo storage cho mỗi attempt.
Chọn kiểu và độ rộng đủ giữ biểu thức capture. Dữ liệu bị cắt hoặc đổi signedness vẫn có thể được lưu ổn định nhưng mang sai giá trị.
Biến cũng cần được gán hợp lệ trước khi đọc. Không suy từ một đường capture đơn rằng mọi nhánh and/or/intersect đều có thể chia sẻ và đọc biến theo cùng cách.
Bốn lỗi khi lưu dữ liệu cho attempt
- Dùng giá trị gần nhất để kiểm mọi yêu cầu đang chờ.
- Cho mọi lần capture cùng một giá trị nên không phát hiện mất isolation.
- Chỉ kiểm out_valid mà chưa đối chiếu nội dung.
- Dùng history sai độ sâu hoặc trước khi lịch sử hợp lệ.
Ghi lại tick start, dữ liệu được giữ và deadline. Sau đó mới chọn local storage, history cố định hay scoreboard theo ID.
Tự truy nguồn dữ liệu của từng phép so
- Tại tick 3, biến local, latest và history một tick lần lượt lấy dữ liệu từ đâu?
- Nếu đổi dữ liệu của start tại tick 2 thành 3, lỗi dùng chung storage nào sẽ khó thấy hơn?
- Nếu chuyển deadline từ hai tick xuống một tick, bảng cần đổi những dòng nào?
- Vì sao vẫn cần giữ response sai tại tick 9 khi kiểm một checker?
Kiểm tra
Bằng chứng kiểm chứng
Expected tính trước chạy: LOCAL VAR CHECK samples=12 starts=4 responses=4 local_failures=1 local_mask=512 shared_failures=3 shared_mask=776 past_failures=1 past_mask=512 time_ns=120. Mười hai tick chạy qua deadline cuối 9 tới 12, và thời gian kết thúc thật được kiểm bằng $time.
Property shared được đặt cạnh property local để minh họa lỗi lưu expected, không phải một đề xuất checker tốt. Property past là đối chiếu đúng cho contract cố định đang dùng. Cả sample/start/response count và các mask đều được kiểm, nên đổi stimulus hoặc tắt checker không thể chỉ giữ một dòng output đẹp.
Giữ nguyên bốn mutant: capture data+1, dùng latest thay v, đổi deadline hai tick thành một tick và đổi history hai tick thành một tick. Chúng parse/build rồi bị bắt ở runtime. Property shared là đối chứng sai có chủ đích; property history là đối chiếu đúng trong hợp đồng độ trễ cố định này. Mô phỏng chỉ xét unsigned 4 bit, dữ liệu 0–9 và mô hình 2-state; chưa kiểm X/Z hoặc flow biến qua các nhánh sequence phức tạp.
Nguồn và mức độ đối chiếu
- IEEE 1800-2023 SystemVerilog LRM, Assertion local variables, match items and variable flow — chưa đối chiếu LRM. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Local Variables in Assertion Properties — bản chụp resources.zip, The Problem: A Signal Can Change Before You're Ready to Check It; Declaring and Assigning a Local Variable; Comparing Both Versions on the Same Trace; Local Variables Track Each Attempt Independently; Common Beginner Mistakes. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thí nghiệm nguyên bản B8.local-vars, Four overlapping captures, fixed-depth history comparison and four runtime mutants. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, Sequence operators and assertion local variables — chưa đối chiếu LRM. Chưa đối chiếu với văn bản nguồn (chưa mở).