Class handle và object: hai tên có thể cùng sửa một transaction

Khoảng 45 phútMức 1/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 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.

[1]

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.

Class handle và object: hai tên có thể cùng sửa một transaction

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.

tb.sv testbench
`timescale 1ns/1psclass Sample;  int value;  function new(int initial_value=0);    value=initial_value;  endfunctionendclassmodule tb_handle;  Sample first,alias_handle,independent;  Sample items[],copies[];  int total=0;  initial begin    if(first!=null||alias_handle!=null)$fatal(1,"handles should start null");    first=new(10);alias_handle=first;    alias_handle.value=20;    independent=new(20);    if(first.value!=20||first!=alias_handle||first==independent||independent.value!=20)      $fatal(1,"handle assignment shares identity, not value clone");    first=null;    if(alias_handle==null||alias_handle.value!=20)$fatal(1,"clearing one handle lost reachable object");    items=new[4];    foreach(items[i])begin      if(items[i]!=null)$fatal(1,"allocating array must not construct elements");      items[i]=new(3*(i+1));    end    copies=items;    if(copies.size()!=4)$fatal(1,"array copy size");    copies[1].value=60;    copies[0]=new(99);    if(items[0].value!=3||items[1].value!=60||copies[0].value!=99||copies[0]==items[0])      $fatal(1,"array storage copy must preserve element-handle sharing only");    foreach(items[i])total+=items[i].value;    if(total!=84)$fatal(1,"handle array total");    $display("HANDLE CHECK initial_null=2 shared_value=20 independent_identity=1 array_sum=84 replaced_original=3 survivor=20");    $finish;  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: HANDLE CHECK initial_null=2 shared_value=20 independent_identity=1 array_sum=84 replaced_original=3 survivor=20

Chỉ source và self-check đã nêu, Verilator 2-state; không claim X/Z, synthesis, garbage-collection timing hoặc đầy đủ mọi class feature.

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.

[2]

Tự kiểm tra

Tự kiểm tra: class-handle

  1. Sau copies=items, sửa copies[1].value=60 rồi thay copies[0]=new(99), tổng items bằng bao nhiêu?
  2. Hai lần new tạo hai Sample có value 20. Handle của chúng có bằng nhau không?
  3. Ngay sau items=new[4], điều gì đúng trước foreach gọi new?
  4. First=null sau alias_handle=first làm alias_handle thế nào?
  5. Thay copies[0] bằng một object mới ảnh hưởng items[0] thế nào?

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

  1. 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.
  2. 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.
  3. 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ở).
  4. 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.
  5. 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.