Dynamic array: resize có giữ dữ liệu hay tạo lại từ đầu

Khoảng 40 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ẽ

  • Dự đoán size mặc định, assignment và new[]
  • Giữ hoặc bỏ dữ liệu khi resize bằng lựa chọn rõ
  • Phân biệt value copy của array với shared class handle

Tăng length không mặc nhiên giữ sample cũ

Một monitor nhận thêm kết quả và cần thêm hai slot. Nếu dùng new[5] trên array 3 phần tử mà quên copy initializer, dữ liệu đã thu có thể biến thành default. Hãy phân biệt yêu cầu capacity mới với yêu cầu bảo toàn nội dung trước khi chọn cú pháp.

Khai báo rỗng chưa có element để truy cập

Dynamic array có [] sau tên và size mặc định 0. Size là số phần tử hiện có, không phải width của mỗi element. new[n] tạo n element với default của element type; ví dụ element int default 0. Không ghi data[0] khi size 0 rồi trông chờ array tự lớn lên. [1]

Assignment có thể xác định size đích

Gán literal 11/22/33 trực tiếp vào data tạo size 3 trong phép thử, không cần gọi new trước mỗi assignment. Copy sang snapshot tạo giá trị array độc lập trong ví dụ int. Điều này khác gán class handle, vốn có thể chia sẻ object; nếu element là handle thì copy element không tự deep-copy object.

Copy initializer giữ prefix và default phần mới

new[5](data) từ 11/22/33 cho 11/22/33/0/0. Tăng size không có nghĩa các phần tử mới mang giá trị của phần tử cuối. TB kiểm cả ba phần tử cũ, cả hai phần tử mới và size, tránh chỉ đọc size rồi gọi preserve thành công.

Thu nhỏ giữ phần nào cũng cần expected

Sau snapshot=data, đổi data[0] thành 99 rồi new[2](data). Data còn 99/22, snapshot vẫn size 5 với đầu 11. Những phần tử vượt size mới không còn trong data. Nếu cần lại lịch sử ấy, phải lưu ở collection khác theo contract, không dựa vào capacity nội bộ của simulator.

Không có initializer là chọn dữ liệu mới

new[2] không có (data) tạo hai int 0 trong phép thử; đó không phải phép giữ hai phần tử đầu. Sử dụng khi muốn bỏ nội dung là hợp lệ, nhưng không dùng để mở rộng một packet đang tích lũy. Đặt assertion cho prefix cũ ngay sau resize nếu việc giữ dữ liệu là yêu cầu.

Delete xoá toàn bộ dynamic array

delete() không nhận index trong ví dụ và đưa size về 0. Nó không xoá snapshot độc lập. Khi cần insert/remove từng element thường xuyên, queue thường diễn đạt thao tác rõ hơn; đây là quyết định API/contract, không phải benchmark chứng minh queue luôn nhanh hơn. [2]

Grow, shrink, fresh allocation và chín kích thước

Expected trước chạy: grow 5/shrink 2, snapshotfirst 11, fresh 0; thử n 0..8 với data[i]=i+1, sum n(n+1)/2, cuối 36.

Thí nghiệm dynamic

Kỳ vọng tính trước chạy: 11/22/33 grow 5 preserve+0/0;copy 5 beforemutate 99/shrink 2;freshdefaults 0;size 0..8 sums 0..36.

tb_dynamic.sv testbench
module tb_dynamic;  int data[],snapshot[];  int n,total;  initial begin    if(data.size()!=0) $fatal(1,"dynamic default size");    data='{11,22,33};    data=new[5](data);    if(data.size()!=5||data[0]!=11||data[1]!=22||data[2]!=33||data[3]!=0||data[4]!=0) $fatal(1,"dynamic preserve growth");    snapshot=data;data[0]=99;data=new[2](data);    if(data.size()!=2||data[0]!=99||data[1]!=22||snapshot.size()!=5||snapshot[0]!=11) $fatal(1,"dynamic shrink/copy");    data=new[2];if(data[0]!=0||data[1]!=0) $fatal(1,"fresh allocation defaults");    data.delete();if(data.size()!=0||snapshot.size()!=5) $fatal(1,"delete independence");    for(n=0;n<=8;n++) begin      data=new[n];total=0;      foreach(data[i])begin data[i]=i+1;total+=data[i];end      if(data.size()!=n||total!=n*(n+1)/2) $fatal(1,"dynamic size/value n=%0d",n);    end    $display("DYNAMIC CHECK grow=5 shrink=2 saved_first=11 fresh_zero=1 sizes=9 last_sum=36");    $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: DYNAMIC CHECK grow=5 shrink=2 saved_first=11 fresh_zero=1 sizes=9 last_sum=36

Chỉ dynamic array chứa int với size 0..8 và các resize/copy trong TB; không claim allocation failure, class-object deep copy hoặc synthesis.

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.

Có size 0 trong miền test, không truy cập element khi không tồn tại. Không claim mọi allocation failure hoặc hiệu năng. [3]

Tự kiểm tra

Tự kiểm tra: dynamic

  1. Data 11/22/33, new[5](data) tạo gì?
  2. New[2] không initializer trên data 99/22 tạo gì?
  3. Snapshot copy trước khi data[0] đổi 99, snapshotfirst là gì?
  4. Dynamic array trước sizing và sau delete có size nào?
  5. Data[i]=i+1 với size 8 có tổng bao nhiêu?

Chọn rõ giữ prefix hay bỏ dữ liệu

Ghi old size, new size, expected prefix và default của phần mở rộng. Kiểm copy độc lập bằng mutation sau copy. Dynamic array phù hợp một khối dữ liệu có size runtime; queue phù hợp các thao tác đầu/cuối liên tục.

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

  1. SystemVerilog Dynamic Array — bản chụp resources.zip, Dynamic declaration và sizing. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. SystemVerilog Dynamic Array — bản chụp resources.zip, Methods và copy. Trích dẫn; nguồn đã đọc các mục liên quan.
  3. Thí nghiệm nguyên bản ex.b2.dynamic, Bằng chứng. Trích dẫn; nguồn đã đọc toàn văn.
  4. IEEE 1800-2023 SystemVerilog LRM, dynamic array and collection semantics. Chưa đối chiếu với văn bản nguồn (chưa mở).
  5. Thí nghiệm nguyên bản ex.b2.dynamic, Source, self-checks, metadata và verification.json; probe limits. Trích dẫn; nguồn đã đọc toàn văn.
  6. SystemVerilog Dynamic Array — bản chụp resources.zip, Syntax; Dynamic Array Methods; How to Add New Items to a Dynamic Array?; Copying Dynamic Array Example; Common Mistakes. Trích dẫn; nguồn đã đọc các mục liên quan.