Chọn collection cho scoreboard: ordering, ID và dữ liệu còn thiếu

Khoảng 40 phútMức 3/3Bản nháp: một số khẳng định chưa đối chiếu spec

Sau bài này bạn sẽ

  • Chọn queue cho in-order và associative lookup khi response reorder
  • Từ chối duplicate/unexpected ID mà không phá expected data
  • Kiểm final accounting và giữ pending khi payload sai

Data structure sai có thể làm checker báo lỗi giả

Ba request đến theoID 3/1/2, nhưng contract cho response theo 1/3/2. Queue FIFO head 3 không phải expected response đầu nếu reorder được phép. Mô hình cần lookup theoID; ngược lại, dùng lookup cho một interface bắt buộc in-order có thể vô tình bỏ lọt lỗi ordering.

Chốt tối đa một outstanding cho mỗi ID

Ví dụ giả định mỗiID 4 bit có tối đa một request chưa match, payload 8 bit phải bằng expected, ID được dùng lại sau completion. Đây là contract của model minh hoạ, không là rule của một protocol bị hoãn. Nếu thật sự có nhiều outstanding cùngID, phải đổi model thành queue mỗiID hoặc cơ chế phù hợp khác.

Cùng request history, head FIFO vẫn 3

Test giữ queue history 3/1/2 để minh hoạ head 3 khác response đầu 1. Associative model lưu expected payload theo key và chấp nhận response 1/3/2 đúng dữ liệu. Không xoá ordering check ở một sản phẩm đòi in-order chỉ vì lookup tiện hơn. [1]

Duplicate không được overwrite dữ liệu pending

Sau requestID 1 payload 10 hex, một requestID 1 payloadff bị từ chối. Pending 1 vẫn 10, số accepted không tăng. Nếu chỉ viết pending[id]=data thì thao tác array hợp lệ nhưng checker đã mất expected của request cũ. Test kiểm cả return, counter và payload được bảo toàn.

Response không có pending là lỗi riêng

Sau match ID 1 đầu tiên, responseID 1 lặp lại bị tính unexpected. Đọc một default value từ missingkey rồi so payload không đủ phân biệt trường hợp này. Model kiểm exists trước, không tự thêm request giả hoặc xoá một transaction khác. [2]

Payload sai chưa được tiêu thụ expected

ID 1 được dùng lại với expected 11 hex; response 12 hex bị báo bad_data nhưng pending vẫn còn 11. Response đúng 11 sau đó match và xoá entry. Chính sách giữ expected khi bad response là contract bài này; trong hệ thống thật còn cần quyết định có tiếp tục regression và báo nhiều lỗi hay dừng.

Pending rỗng chưa đủ, phải kiểm thống kê

Expected có 4 requestaccepted và 4 match, duplicate 1/unexpected 1/baddata 1, cuốipending 0. Nếu caller xoá mọi entry khi lỗi thì pending vẫn có thể rỗng nhưng counters sai. Kiểm lẫn return status, data, entry count và accounting giúp bắt các đường bỏ qua lỗi.

Một model nhỏ có cả giao dịch hợp lệ và lỗi

Expected trước chạy: ID 3/1/2 được trả 1/3/2, reuseID 1 thành request thứ 4; các lỗi được đếm riêng 1 mỗi loại, không phá state cần cho response tiếp.

Thí nghiệm choose

Kỳ vọng tính trước chạy: IDs 3/1/2 response 1/3/2 legal,duplicateID 1 rejected,unexpectedID 1 afterdelete,IDreuse 1 new 11,baddata 12 retainedpending;4 matched.

tb_scoreboard.sv testbench
module tb_scoreboard;  typedef struct packed {bit[3:0] id;bit[7:0] payload;} txn_t;  txn_t ordered[$],tx;  bit[7:0] pending[bit[3:0]];  int accepted=0,matched=0,duplicates=0,unexpected=0,bad_data=0;  function automatic bit register_request(input bit[3:0] id,input bit[7:0] data);    if(pending.exists(id))begin duplicates++;return 0;end    pending[id]=data;accepted++;return 1;  endfunction  function automatic bit match_response(input bit[3:0] id,input bit[7:0] data);    if(!pending.exists(id))begin unexpected++;return 0;end    if(pending[id]!=data)begin bad_data++;return 0;end    pending.delete(id);matched++;return 1;  endfunction  initial begin    if(!register_request(3,8'h30)||!register_request(1,8'h10)||!register_request(2,8'h20)) $fatal(1,"scoreboard request");    if(register_request(1,8'hff)||pending[1]!=8'h10) $fatal(1,"duplicate overwrites expected data");    ordered.push_back('{id:3,payload:8'h30});ordered.push_back('{id:1,payload:8'h10});ordered.push_back('{id:2,payload:8'h20});    // First actual response has ID1, unlike FIFO head3; key lookup is required for out-of-order contract.    tx=ordered[0];if(tx.id!=3) $fatal(1,"ordered reference head");    if(!match_response(1,8'h10)||!match_response(3,8'h30)||!match_response(2,8'h20)) $fatal(1,"out-of-order match");    if(match_response(1,8'h10)||!register_request(1,8'h11)) $fatal(1,"unexpected response or ID reuse");    if(match_response(1,8'h12)||!pending.exists(1)||pending[1]!=8'h11) $fatal(1,"bad data destroys pending request");    if(!match_response(1,8'h11)||pending.num()!=0||accepted!=4||matched!=4||duplicates!=1||unexpected!=1||bad_data!=1)      $fatal(1,"scoreboard final accounting");    $display("SCOREBOARD CHECK accepted=4 matched=4 duplicate=1 unexpected=1 bad_data=1 pending=0 fifo_head=3 first_response=1");    $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: SCOREBOARD CHECK accepted=4 matched=4 duplicate=1 unexpected=1 bad_data=1 pending=0 fifo_head=3 first_response=1

Một process, tối đa một outstanding/ID 4 bit, value payload 8 bit và IDreuse sau completion. Không claim reset/timeout/concurrency, class deep copy hoặc protocol cụ thể.

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.

Không claim class-object deep copy, timeout, reset, concurrent mailbox hoặc full DV environment. Model chạy một process để cô lập semantics collection. [3]

Tự kiểm tra

Tự kiểm tra: choose

  1. Requests 3/1/2, response 1/3/2 được phép reorder: chọn lookup nào?
  2. PendingID 1 payload 10 hex, requestID 1 ff trùng: model làm gì?
  3. PendingID 1 payload 11, response 12 sai: model làm gì?
  4. Cuối testcase có bao nhiêu accepted và matched?
  5. Model trong bài giả định gì cho mỗiID?

Chọn theo quan hệ cần bảo toàn

Queue giữ quan hệ thứ tự; associative key giúp lookup sparse identity; dynamic array phù hợp khối có size runtime. Chọn đúng thứ cần kiểm rồi viết negative cases duplicate/missing/wrongdata. Data structure là cơ chế, contract mới quyết định response nào đúng.

  • Số slot cố định: fixed unpacked array.
  • Khối có size runtime: dynamic array.
  • Thêm/bớt ở đầu/cuối: queue.
  • Lookup theo ID thưa: associative array.

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

  1. SystemVerilog Queue — bản chụp resources.zip, Queue và lookup. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. SystemVerilog Associative Array — bản chụp resources.zip, Existence. Trích dẫn; nguồn đã đọc các mục liên quan.
  3. Thí nghiệm nguyên bản ex.b2.choose, Bằng chứng. Trích dẫn; nguồn đã đọc toàn văn.
  4. IEEE 1800-2023 SystemVerilog LRM, choose 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.choose, Source, self-checks, metadata và verification.json; probe limits. Trích dẫn; nguồn đã đọc toàn văn.
  6. SystemVerilog Associative Array — bản chụp resources.zip, Syntax; Associative Array Methods; Associative Array Methods Example. Trích dẫn; nguồn đã đọc các mục liên quan.
  7. 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.