Class handle và object: hai tên có thể cùng sửa một transaction
Tiên quyết
Sau bài này bạn sẽ
- Phân biệt handle null, cấp phát object và gán handle
- Theo dõi identity khi nhiều handle cùng trỏ một object
- Phân biệt copy array storage với clone các object trong array
Hai tên không nhất thiết là hai bản dữ liệu
Monitor lưu một transaction rồi tái sử dụng nó cho lần nhận kế tiếp. Nếu scoreboard chỉ giữ handle, dữ liệu đã lưu có thể đổi theo lần sửa tiếp theo. Trước khi hỏi giá trị nào đúng, hãy vẽ xem có bao nhiêu object và mỗi handle đang trỏ tới đâu.
Khai báo handle chưa tạo object
Trong ví dụ, Sample first, alias_handle; tạo hai biến handle, cả hai đều null trước khi cấp phát. So sánh handle với null không đọc một property. Chỉ truy cập member sau khi bảo đảm handle hợp lệ; main không cố tình dereference null rồi lấy diagnostic của một tool làm quy tắc portable.
New tạo object, assignment sao chép handle
first = new(10) tạo object có value 10. alias_handle = first chỉ làm hai handle trỏ cùng object. Khi sửa alias_handle.value = 20, đọc first.value cũng được 20. Đây là chia sẻ identity, không phải một cơ chế sao chép transaction độc lập.
Hai object có cùng field vẫn có identity khác
independent = new(20) tạo một object khác dù value bằng object trước. Main kiểm cả field value và phép so sánh handle; first == independent phải false trong trường hợp này. Nếu muốn so nội dung transaction, viết comparator theo contract của bạn, đừng thay bằng equality của handle.
Gán null chỉ bỏ một đường tham chiếu
Sau first = null, alias_handle vẫn trỏ object value 20. Không được coi việc xoá một handle là xoá object đang được nơi khác dùng. Example không đo thời điểm garbage collection, dung lượng heap hay destructor; nó chỉ kiểm object vẫn truy cập được qua handle còn sống.
Cấp phát array không tự tạo từng object
items = new[4] cấp phát bốn phần tử handle, ban đầu mỗi phần tử vẫn null. Vòng foreach phải gọi new cho từng phần tử để có bốn object với value 3/6/9/12. Array size hợp lệ không đủ để bảo đảm member access an toàn.
Copy array không clone object mà phần tử trỏ tới
copies = items tạo bản copy storage của dynamic array nhưng mỗi phần tử giữ cùng handle. Sửa copies[1].value = 60 làm items[1].value thành 60. Ngược lại, gán riêng copies[0] = new(99) thay handle trong copies; items[0] vẫn trỏ object value 3. Tổng items cuối là 3+60+9+12=84.
Kiểm identity, null và hai tầng storage
Expected tính trước chạy: hai handle đầu null; giá trị chia sẻ 20; object độc lập không cùng identity; tổng items 84; items[0] giữ 3 và alias sống sau khi first=null. Main dùng Verilator 2-state, không claim X/Z hoặc synthesis.
Tự kiểm tra
Review ownership trước khi lưu handle
Ở ranh giới monitor/scoreboard, ghi rõ bên gửi có được sửa object sau khi gửi hay không. Nếu bên nhận cần snapshot độc lập, phải có chính sách copy phù hợp; bài này chưa triển khai deep copy. Vẽ riêng array storage, từng handle và object để tìm chỗ alias có thể làm sai expected.
Nguồn và mức độ đối chiếu
- SystemVerilog Class Handle — bản chụp resources.zip, Nguồn đào tạo đã đọc theo section. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thí nghiệm nguyên bản ex.b5.class-handle, Bằng chứng thực nghiệm. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, Class handles, construction, static and const properties. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Thí nghiệm nguyên bản ex.b5.class-handle, Source, self-checks, verification.json và mutation/capability probes. Trích dẫn; nguồn đã đọc toàn văn.
- SystemVerilog Class Handle — bản chụp resources.zip, What Is a Class Handle?; What Is a Class Object?; What Happens When Two Handles Point to the Same Object?; Fixed Array; Dynamic Array. Trích dẫn; nguồn đã đọc các mục liên quan.