Subroutine SV: ref nhìn thấy ngay, output chép khi trả về

Khoảng 40 phútMức 2/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 input copy, output copy-out và ref alias trong task có thời gian
  • Dùng automatic, default và named argument với expected rõ
  • Giới hạn ý nghĩa const ref vào dữ liệu được tham chiếu, không suy deep immutability

Cùng giá trị cuối chưa chứng minh cùng cách truyền

Hai task đều sửa một số rồi chờ 3 ns. Với ref, caller có thể thấy lần sửa đầu trước khi task xong; với output, caller nhận kết quả khi task trả về. Nếu chỉ đọc sau join, bạn có thể bỏ lỡ khác biệt rất quan trọng cho monitor hoặc driver.

Input copy và output copy-out là hai kênh khác nhau

Change_copy nhận original 10, tính target 12 rồi 14 với delta 2. Caller copy_value vẫn-1 tại 1 ns và thành 14 khi task xong 3 ns. Giá trị target nội bộ không tự trở thành một alias của biến caller. Hãy xem direction từng argument, không suy từ tên task. [1]

Ref trỏ vào biến của caller

Change_ref nhận ref_value10, dùng delta mặc định 1: ghi 11 ngay đầu call rồi 12 sau 3 ns. Quan sát tại 1 ns thấy 11 dù task chưa trả về. Actual phải là biến phù hợp về type/lifetime; không coi một expression bất kỳ như storage có thể ghi. [2]

Automatic là lựa chọn có ý nghĩa với ref

Task/function trong example đều automatic. Ref formal gắn với một call và một biến caller; đừng dùng static subroutine như một đường tắt để chia sẻ trạng thái giữa các caller. Main chỉ có hai task trên hai target khác nhau, không claim mọi aliasing/concurrency/lifetime edge case.

Default và named call phải được đọc tại call site

Change_ref bỏ delta nên dùng 1. Change_copy chỉ định original/target/delta theo tên nên lấy delta 2. Nếu sửa default, các call bỏ argument có thể đổi hành vi dù call site không đổi. Test kiểm cả caller dùng default và caller override; không có benchmark về overhead.

Const ref cho read-only view của array int

Function total nhận const ref array ba int 6/7/8, trả 21 và không đổi phần tử đầu 6. Probe viết values[0]=99 bị pyslang từ chối với AssignmentToConstVar. Đó là bằng chứng về direct assignment trong trường hợp này, không nói const handle sẽ deep-freeze class object hoặc tự clone transaction.

Kiểm trong lúc task đang chạy, không chỉ sau join

Observer tại 1 ns tách ref 11 với output-1; join tại 3 kiểm 12/14. Function total trong ví dụ không có timing control; task mang #3. Watchdog 10 ns bắt call không kết thúc. Không suy mọi rule về fork trong function hoặc callback phức tạp từ subset đang chạy.

Hai thời điểm quan sát và một const-ref sum

Expected trước chạy: ref 11/output-1 ở 1 ns; ref 12/output 14 ở 3 ns; constsum 21 và datafirst 6.

Thí nghiệm subroutines

Tính trước:ref10 dùng defaultdelta 1 thấy 11 t 1 và 12 t 3; outputdelta 2 copyout 14 t 3, trướcđó-1; constrefarray 6/7/8 sum 21.

tb_ref.sv testbench
`timescale 1ns/1psmodule tb_ref;  int ref_value=10,copy_value=-1;  int data[3]='{6,7,8};  function automatic int total(const ref int values[3]);    int result=0;    foreach(values[i])result+=values[i];    return result;  endfunction  task automatic change_ref(ref int target,input int delta=1);    target+=delta;#3;target+=delta;  endtask  task automatic change_copy(input int original,output int target,input int delta=1);    target=original+delta;#3;target+=delta;  endtask  initial begin    fork      change_ref(ref_value);      change_copy(.original(10),.target(copy_value),.delta(2));      begin        #1;        if(ref_value!=11||copy_value!=-1)$fatal(1,"ref must be visible before task return");        $display("REF MID at=1 reference=11 output=-1");      end    join    if($time!=3||ref_value!=12||copy_value!=14||total(data)!=21||data[0]!=6)      $fatal(1,"ref/default/output-copyout/constref result");    $display("REF CHECK at=3 reference=12 output=14 const_sum=21 unchanged_first=6");    $finish;  end  initial begin #10;$fatal(1,"ref watchdog");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: REF MID at=1 reference=11 output=-1REF CHECK at=3 reference=12 output=14 const_sum=21 unchanged_first=6

Chỉ hai automatic tasks với ref/output ở 1/3 ns, default/namedargs và constrefintarray 3 element. Không claim mọi lifetime/aliasrace, class deep constness, copy-cost benchmark 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.

Verilator 2-state thực thi cả task có thời gian, default/named args và kiểm copy-out; không claim X/Z hoặc synthesis. [3]

Tự kiểm tra

Tự kiểm tra: subroutines

  1. Tại 1 ns, ref_value và copy_value trong TB là gì?
  2. Khi join ở 3 ns, ref và output cho gì?
  3. Constref array 6/7/8 trả sum và first sau gọi thế nào?
  4. Call change_copy dùng delta 2 nhờ đâu?
  5. Ví dụ ref subroutine dùng lifetime nào?

Vẽ đường đọc và ghi qua argument

Chốt caller variable nào đổi, đổi lúc nào và ai sở hữu lifetime. Thử đọc trước return để phân biệt alias với copy-out. Với dữ liệu chỉ đọc, kiểm const rule bằng compiler và giữ scope claim đúng element type đang dùng.

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

  1. SystemVerilog Functions & Tasks — bản chụp resources.zip, Value và directions. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. SystemVerilog Functions & Tasks — bản chụp resources.zip, Reference passing. Trích dẫn; nguồn đã đọc các mục liên quan.
  3. Thí nghiệm nguyên bản ex.b3.subroutines, Bằng chứng. Trích dẫn; nguồn đã đọc toàn văn.
  4. IEEE 1800-2023 SystemVerilog LRM, subroutines procedural/package 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.b3.subroutines, Source, self-checks, metadata, verification.json và mutation probes. Trích dẫn; nguồn đã đọc toàn văn.
  6. IEEE 1800-2023 SystemVerilog LRM, subroutines procedural semantics. Chưa đối chiếu với văn bản nguồn (chưa mở).
  7. SystemVerilog Functions & Tasks — bản chụp resources.zip, Default Argument Values; Passing Arguments by Value; Passing Arguments by Reference; const ref: Reference Efficiency Without the Mutability Risk. Trích dẫn; nguồn đã đọc các mục liên quan.