Queue: thao tác đầu/cuối và thứ tự dữ liệu cần được kiểm

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ẽ

  • Phân biệt push/pop hai đầu và insert/delete theo index
  • Tính capacity bounded queue từ chỉ số cuối
  • Kiểm copy value và tránh đọc hoặc pop queue rỗng

Queue không tự bảo đảm bạn dùng đúng thứ tự

Một collection hỗ trợ cả hai đầu có thể được dùng làm FIFO hoặc stack. Push_back rồi pop_front là FIFO; đổi sang pop_back sẽ lấy phần tử mới nhất. Tên biến pending_queue không chứng minh monitor và checker đang dùng cùng hợp đồng ordering.

Unbounded nghĩa không khai bound tĩnh

Queue khai [$], tự thay đổi size theo thao tác; tài nguyên máy vẫn có giới hạn. Bounded [$:2] có tối đa 3 element với chỉ số 0..2, không phải 2 element. Bài chỉ fill tới capacity ấy, không claim mọi semantics khi overflow. [1]

Ba push và một pop trả giá trị cũ nhất

Push_back4/7/9 tạo queue 4/7/9. Pop_front trả 4 và để lại 7/9. Test kiểm cả return value lẫn state sau pop: một implementation trả đúng 4 nhưng không remove head vẫn phải bị bắt ở snapshot tiếp theo.

Push front và insert dịch vị trí còn lại

Từ 7/9, push_front2 thành 2/7/9. Insert inde x1 value 5 thành 2/5/7/9. Index là vị trí trong state hiện tại, không phải ID ổn định của transaction. Sau các insert/remove, một index đã lưu trước có thể chỉ tới element khác.

Delete index khác pop và delete toàn bộ

Delete index 2 trong 2/5/7/9 bỏ 7, còn 2/5/9. Pop_back sau đó trả 9, còn 2/5. Delete() cuối cùng đưa size 0. Các thao tác không tự kiểm data được bỏ có phải transaction mà scoreboard đã match hay không; caller vẫn cần điều kiện match.

Copy queue int rồi mutate là hai giá trị riêng

Saved=q khi q2/5; đổi q[0] thành 99 không đổi saved 2/5. Nếu queue chứa class handle thì element handle được chép, không tự clone object; case ấy cần cơ chế copy được kiểm riêng ở OOP. Không dùng kết quả int queue để kết luận deep-copy mọi transaction object.

Kiểm size trước khi lấy element

Bài không pop rỗng để lấy một default làm dữ liệu hợp lệ. Với consumer, chỉ pop khi có expected transaction; unexpected response là lỗi khác cần báo. Khi cần lookup theoID với reorder, queue FIFO có thể là mô hình sai dù các method hoạt động đúng; bài choose sẽ làm rõ.

Chín snapshot, hai return value và một bounded capacity

Expected trước chạy: firstpop 4/backpop 9, saved 2/5, boundedcapacity 3, finalsize 0 và 9 snapshotđúng.

Thí nghiệm queue

Kỳ vọng tính trước chạy: 9 queue snapshots,firstpop 4/backpop 9,copy 2/5 survivesmutate 99,deleteempty,boundedlastindex 2 capacity 3.

tb_queue.sv testbench
module tb_queue;  int q[$],saved[$];  int bounded[$:2];  int value,checks=0;  task automatic check_values(input int expected[$]);    if(q.size()!=expected.size()) $fatal(1,"queue size check=%0d",checks);    foreach(expected[i])if(q[i]!=expected[i]) $fatal(1,"queue element check=%0d index=%0d",checks,i);    checks++;  endtask  initial begin    check_values('{});    q.push_back(4);q.push_back(7);q.push_back(9);check_values('{4,7,9});    value=q.pop_front();if(value!=4) $fatal(1,"queue FIFO head");check_values('{7,9});    q.push_front(2);check_values('{2,7,9});    q.insert(1,5);check_values('{2,5,7,9});    q.delete(2);check_values('{2,5,9});    value=q.pop_back();if(value!=9) $fatal(1,"queue back return");check_values('{2,5});    saved=q;q[0]=99;check_values('{99,5});    if(saved.size()!=2||saved[0]!=2||saved[1]!=5) $fatal(1,"queue value copy");    q.delete();check_values('{});    bounded.push_back(1);bounded.push_back(2);bounded.push_back(3);    if(bounded.size()!=3) $fatal(1,"bounded upper index plus one");    $display("QUEUE CHECK snapshots=9 first_pop=4 back_pop=9 saved=2/5 bounded_capacity=3 final_size=0");    $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: QUEUE CHECK snapshots=9 first_pop=4 back_pop=9 saved=2/5 bounded_capacity=3 final_size=0

Chỉ int queue/directed 9 snapshot và bounded fill tới capacity 3; không claim overflow/invalid-index/empty-pop semantics, class deep copy, performance 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.

Mỗi snapshot kiểm size và mọi element, không chỉ log queue bằng mắt. Không claim performance hoặc overflowing/invalid-index method behavior. [2]

Tự kiểm tra

Tự kiểm tra: queue

  1. Push_back4/7/9 rồi pop_front trả gì?
  2. Bounded queue[$:2] có capacity tối đa bao nhiêu?
  3. Queue 2/7/9 insert(1,5) thành gì?
  4. Queue 2/5/7/9 delete(2) còn gì?
  5. Saved=q khiq 2/5, sửa q[0]99 thì saved là gì?

Viết ordering policy trước thao tác collection

Ghi đầu nào là oldest, khi nào được remove và action khi rỗng. Tách index vị trí khỏi ID transaction. Queue giúp diễn đạt thao tác, còn correctness nằm ở contract và checker.

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

  1. SystemVerilog Queue — bản chụp resources.zip, Queue types và methods. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. Thí nghiệm nguyên bản ex.b2.queue, Bằng chứng. Trích dẫn; nguồn đã đọc toàn văn.
  3. IEEE 1800-2023 SystemVerilog LRM, queue array and collection semantics. 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.b2.queue, Source, self-checks, metadata và verification.json; probe limits. Trích dẫn; nguồn đã đọc toàn văn.
  5. SystemVerilog Queue — bản chụp resources.zip, Types of Queues; Syntax; SystemVerilog Queue Methods. Trích dẫn; nguồn đã đọc các mục liên quan.