Time unit, precision và scope: cùng #1.26 không cùng thời điểm

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

  • Quy đổi delay theo time unit rồi làm tròn theo precision của scope
  • Phân biệt mất độ phân giải delay với làm tròn khi đọc $time
  • Giải thích timeunit/timeprecision của module không lấy từ nơi instantiate
  • Định dạng log có đơn vị mà không nhầm với thay đổi simulation time

Delay là một con số cần đơn vị

Hai model đều ghi #1.26, cùng bắt đầu tại t=0 nhưng một model hoàn tất 1.260 ns, model kia 13 ns. Muốn đọc đúng, phải biết time unit và precision của scope có delay, không chỉ nhìn số trong source hoặc đơn vị đang hiển thị của viewer.

Bài dùng fine model có 1 ns/1 ps, coarse model có 10 ns/1 ns và checker có 1 ps/1 ps. Các event được so trên cùng trục ps; không có ba đồng hồ thời gian độc lập chạy tách nhau. [1]

Time unit quyết định #1 dài bao lâu

Trong fine, một đơn vị local bằng 1 ns, nên 1.26 đơn vị bằng 1.26 ns. Trong coarse, một đơn vị bằng 10 ns, nên con số ấy tương ứng 12.6 ns trước khi làm tròn.

TB dùng SystemVerilog timeunit và timeprecision bên trong module. Verilog còn có directive timescale với hai thành phần unit/precision. Chúng phục vụ mô hình simulation, không đặt tần số clock hay constraint STA cho phần cứng tổng hợp. [2]

Precision lượng tử hóa thời điểm event

Fine có bước 1 ps, nên 1.26 ns được giữ ở 1260 ps. Coarse có bước 1 ns;12.6 ns làm tròn thành 13 ns, tương ứng 13000 ps. Có module khác với precision 1 ps không làm delay coarse tự lấy lại phần 0.6 ns đã bị lượng tử hóa.

Đây là phép tính trước khi chạy; TB cố ý tránh giá trị đúng nửa bước để không suy rộng cách xử lý mọi tie case. Precision cần phù hợp mô hình; chọn rất nhỏ không tự làm model có tính chính xác vật lý cao hơn. [3]

Scope khai báo khác vị trí instantiate

Checker dùng đơn vị 1 ps và instantiate cả fine lẫn coarse. Hai child không nhận đơn vị 1 ps ấy: khai báo local của từng module định nghĩa cách hiểu delay của chúng. Source còn đặt directive 100 ns/10 ns trước các module để làm rõ các local declaration vẫn quyết định ví dụ.

Với source cũ dựa vào directive timescale, thứ tự văn bản, include và cấu hình compilation unit có thể ảnh hưởng module không khai báo riêng. Tài liệu có ví dụ carry-over qua file; đừng mặc định mọi simulator gom file thành cùng một compilation unit. TB hiện không kiểm mọi include/file-list configuration.

Khi tích hợp IP, xem khai báo của model và lệnh compile thực tế; đừng suy time unit từ vị trí hierarchy. Quy tắc chuẩn đầy đủ còn [4]. [5]

$time và $realtime có thể trả hai cách biểu diễn

Fine tại 1.26 ns đọc local $realtime là 1.26 nhưng $time là số nguyên 1. Coarse tại 13 ns đọc local realtime 1.3 đơn vị 10 ns, còn $time cũng là 1. Cùng số nguyên 1 không có nghĩa hai model xảy ra cùng thời điểm.

Đây là lần làm tròn khi đọc thời gian ở đơn vị local, khác với lượng tử hóa delay trước đó. Nếu đã dùng giá trị nguyên 1 thay cho 1.26 rồi mới đổi format, phần lẻ đã mất không được phục hồi. Checker ở scope 1 ps ghi timestamp 1260/13000 bằng số nguyên để đối chiếu hai event. [6]

$timeformat đổi cách in, không đổi lịch

TB đặt $timeformat(-9, 3, " ns", 0) tại đầu mô phỏng: in theo ns, ba chữ số thập phân, suffix rõ. Format %0t không thêm padding. Mỗi child format realtime ngay trong scope của mình, nên log lần lượt 1.260 ns và 13.000 ns.

Một điểm dễ bỏ sót: biến real đã lưu chỉ là số; nếu mang số 1.3 của coarse sang checker 1 ps rồi dùng %t, formatter không tự mang theo “đơn vị 10 ns của nguồn”. Cần đổi đơn vị rõ hoặc format tại scope lấy số, như TB đang làm.

Tại checker 14000 ps, đổi timeformat sang ps làm log hiện 14000 ps mà timestamp không đổi. Setting này ảnh hưởng cách in về sau; không thay precision, không chạy lại event và không đổi delay đã lượng tử hóa. [7]

Đối chiếu 1260 ps với 13000 ps

Kỳ vọng trước chạy: fine event 1260 ps, coarse event 13000 ps, checker tại 14000 ps. Hai integer local đều 1, hai real local lần lượt 1.26/1.3; chuỗi định dạng 1.260 ns/13.000 ns.

Cùng #1.26, hai scope và hai thời điểm thật

Tách timeunit/precision, lượng tử hóa delay, $time/$realtime và định dạng log bằng hai model có scope riêng.

tb_timescale.sv testbench
// Deliberately different from every module's explicit local declaration.`timescale 100ns/10nsmodule fine_clock_model(output reg done = 0);  timeunit 1ns;  timeprecision 1ps;  realtime fraction;  time integral;  string stamp;  initial begin    #1.26;    fraction = $realtime;    integral = $time;    stamp = $sformatf("%0t", $realtime);    done = 1;    $display("TIME FINE local_real=%0.3f local_integer=%0d formatted=%s", fraction, integral, stamp);  endendmodule module coarse_clock_model(output reg done = 0);  timeunit 10ns;  timeprecision 1ns;  realtime fraction;  time integral;  string stamp;  initial begin    #1.26; // 12.6ns rounds to13ns on this module's1ns grid.    fraction = $realtime;    integral = $time;    stamp = $sformatf("%0t", $realtime);    done = 1;    $display("TIME COARSE local_real=%0.3f local_integer=%0d formatted=%s", fraction, integral, stamp);  endendmodule module tb_timescale;  timeunit 1ps;  timeprecision 1ps;  wire fine_done, coarse_done;  time fine_ps = 0, coarse_ps = 0;  fine_clock_model fine(fine_done);  coarse_clock_model coarse(coarse_done);  always @(posedge fine_done) fine_ps = $time;  always @(posedge coarse_done) coarse_ps = $time;  initial begin    $timeformat(-9, 3, " ns", 0);    #14000; // 14000ps=14ns in this scope; after both child events.    if (fine_done !== 1 || coarse_done !== 1 || fine_ps != 1260 || coarse_ps != 13000 ||        fine.integral != 1 || coarse.integral != 1 ||        fine.fraction < 1.25999 || fine.fraction > 1.26001 ||        coarse.fraction < 1.29999 || coarse.fraction > 1.30001 ||        fine.stamp != "1.260 ns" || coarse.stamp != "13.000 ns")      $fatal(1, "time units/rounding/formatting mismatch");    $display("TIME CHECK fine_ps=%0d coarse_ps=%0d checker_ps=%0d", fine_ps, coarse_ps, $time);    // Formatting changes representation, not simulation time or event history.    $timeformat(-12, 0, " ps", 0);    $display("TIME FORMAT now=%0t unchanged_ps=%0d", $realtime, $time);    if ($sformatf("%0t", $realtime) != "14000 ps" || $time != 14000)      $fatal(1, "timeformat changed simulation time");    $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 (Icarus Verilog 11.0, 4-state)

Output phải khớp: TIME FINE local_real=1.260 local_integer=1 formatted=1.260 nsTIME COARSE local_real=1.300 local_integer=1 formatted=13.000 nsTIME CHECK fine_ps=1260 coarse_ps=13000 checker_ps=14000TIME FORMAT now=14000 ps unchanged_ps=14000

Chỉ kiểm scope timeunit/timeprecision khai báo tường minh và ba mốc đã viết; không kiểm mọi quy tắc compilation-unit/include order.

Không dùng delay đúng nửa bước để suy ra mọi trường hợp rounding; các số real được assertion kiểm với tolerance nhỏ.

Không claim synthesis/STA hoặc thời gian silicon. $timeformat chỉ đổi trình bày log, không khôi phục precision đã mất.

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.

Assertions kiểm cả event timestamp, done flag, integer, real với tolerance nhỏ và formatted string. Chỉ nhìn một dòng $time=1 sẽ bỏ lỡ hầu hết khác biệt đang thử. Parser/Icarus chạy đúng phạm vi thí nghiệm, không claim mọi cấu hình tool hoặc STA. [8]

Các bẫy khi ghép model khác đơn vị

  • Quy đổi unit mà quên precision, dự đoán coarse 12.6 ns thay vì 13 ns.
  • Nghĩ time precision toàn thiết kế nhỏ sẽ phục hồi delay đã bị làm tròn trong model coarse.
  • Đọc $time nguyên rồi mong %t phục hồi phần lẻ.
  • Cho rằng module con dùng time unit của module cha.
  • Mang một số real giữa scope mà quên đơn vị nó đại diện.
  • Bỏ đơn vị khỏi log rồi đối chiếu nhầm con trỏ waveform.
  • Coi timeformat là lệnh thay đổi scheduler hoặc timing silicon.

Khi debug, ghi cả khai báo local, biểu thức delay, event timestamp theo đơn vị chung và cấu hình compile. Không dựa vào một default chưa kiểm.

Tự kiểm tra

Tự kiểm tra: timescale

  1. Coarse có unit 10 ns, precision 1 ns. #1.26 từ 0 hoàn tất lúc nào?
  2. Fine có unit 1 ns, precision 1 ps. Checker 1 ps thấy done tại timestamp nào?
  3. $time local của cả fine và coarse đều 1. Có suy ra chúng hoàn tất cùng thời điểm không?
  4. Đổi $timeformat từ ns sang ps tại checker 14000 ps có tác dụng gì?
  5. Checker 1 ps instantiate coarse có timeunit 10 ns/timeprecision 1 ns. #1 trong coarse hiểu thế nào?

Đổi đơn vị trước, xác định điểm làm tròn sau

Tách bốn việc: unit giải thích con số, precision đặt lưới event, hàm đọc thời gian chọn kiểu biểu diễn, format quyết định log. Scope là thông tin bắt buộc của phép suy luận.

Bài giữ draft/LRM needs-spec-check; kết quả thực nghiệm không thay việc đọc các quy tắc chuẩn chưa đối chiếu.

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

  1. Verilog Timescale — bản chụp trong resources.zip, Multiple Timescales. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. Verilog Timescale — bản chụp trong resources.zip, Syntax. Trích dẫn; nguồn đã đọc các mục liên quan.
  3. Verilog Timescale — bản chụp trong resources.zip, Time precision. Trích dẫn; nguồn đã đọc các mục liên quan.
  4. IEEE 1800-2023 SystemVerilog LRM, cần đối chiếu LRM. Chưa đối chiếu với văn bản nguồn (chưa mở).
  5. Verilog Timescale Scope — bản chụp trong resources.zip, Scope. Trích dẫn; nguồn đã đọc các mục liên quan.
  6. Verilog Timescale — bản chụp trong resources.zip, Printing Time. Trích dẫn; nguồn đã đọc các mục liên quan.
  7. Verilog Timeformat — bản chụp trong resources.zip, Syntax và field width. Trích dẫn; nguồn đã đọc các mục liên quan.
  8. Thí nghiệm nguyên bản ex.a7.timescale, Bằng chứng nguyên bản. Trích dẫn; nguồn đã đọc toàn văn.
  9. IEEE 1800-2023 SystemVerilog LRM, Time units/precision; time literals; timeformat and time system functions. Chưa đối chiếu với văn bản nguồn (chưa mở).
  10. Thí nghiệm nguyên bản ex.a7.timescale, TB nguyên bản, assertions và verification.json. Trích dẫn; nguồn đã đọc toàn văn.
  11. IEEE 1800-2023 SystemVerilog LRM, Time units/precision; timescale directive scope; time system functions and timeformat. Chưa đối chiếu với văn bản nguồn (chưa mở).
  12. Verilog Timescale — bản chụp trong resources.zip, Syntax; Printing Time: $time, $realtime and $timeformat; Multiple Timescales in One Design. Trích dẫn; nguồn đã đọc các mục liên quan.
  13. Verilog Timescale Scope — bản chụp trong resources.zip, Standard timescale scope; Scope between Verilog files; SystemVerilog local declarations. Trích dẫn; nguồn đã đọc các mục liên quan.
  14. Verilog Timeformat — bản chụp trong resources.zip, Syntax; %t vs %0t and the Minimum Field Width. Trích dẫn; nguồn đã đọc các mục liên quan.
  15. Thí nghiệm nguyên bản ex.a7.timescale, tb_timescale.sv và verification.json. Trích dẫn; nguồn đã đọc toàn văn.