File I/O và VCD: dữ liệu đọc được phải được kiểm
Tiên quyết
Sau bài này bạn sẽ
- Kiểm descriptor và số trường parse trước khi dùng vector
- Tách dòng lỗi, thiếu record và EOF khỏi kết quả tính DUT
- Chọn scope VCD có mục tiêu và phân biệt tạo file với kiểm trace
- Giữ expected file độc lập với output DUT và tránh dùng lại dữ liệu cũ
Mở được file chưa có nghĩa vector hợp lệ
Một checker đọc thiếu trường có thể giữ expected của dòng trước rồi vẫn so sánh như chưa có chuyện gì. Lúc ấy regression xanh không nói được DUT đúng: bản thân luồng nhập test đã sai.
Ví dụ dùng ba record hexadecimal gồm a, b và tổng 5 bit đã tính tay. Nó kiểm trạng thái mở file, số dòng, số trường, kết quả DUT và EOF, rồi tạo một VCD chỉ chứa scope DUT để phục vụ debug.
Kiểm file descriptor và đóng đúng lúc
$fopen trả descriptor dùng cho các thao tác sau;0 là dấu hiệu mở thất bại cần xử lý trước khi đọc/ghi. TB mở vectors.txt ở mode w, ghi ba dòng, đóng rồi mới mở lại mode r.
Mode w ghi lại file, vì vậy đường dẫn phải là output tạm do test sở hữu. Pipeline chạy trong working directory tạm; ví dụ không trỏ tới file người dùng. Ở test thật đọc vector do model khác sinh, không thay nó bằng output DUT để làm expected. [1]
Đọc dòng trước, kiểm số trường sau
Mỗi lượt dùng fgets lấy một dòng vào buffer, yêu cầu số byte khác 0, rồi sscanf parse ba số hex. Format còn thử đọc một trường text thứ tư; chỉ chấp nhận đúng 3 trường, nên dòng có dữ liệu dư cũng không được coi là record hợp lệ.
Expected phải là giá trị đã biết. Case inequality kiểm tổng DUT với expected; không chạy phép so sánh khi parse chưa đủ trường. Dòng 0f nope 10 được thử riêng: chỉ đọc được trường đầu, nên phải được nhận diện malformed bằng số trường 1.
Buffer có giới hạn 128 ký tự; các record của ví dụ rất ngắn. Parser cho file lớn phải xử lý cả dòng quá dài, comment và schema mong muốn, không giả định ví dụ này đã phủ hết. [2]
EOF không phải một record có giá trị 0
Sau đúng ba record, TB thử fgets lần nữa và yêu cầu 0 byte cùng EOF đã bật. Không đem buffer cũ ra dùng như record mới. Nếu thiếu dòng, kiểm trước parse phải fail; nếu có dòng thứ tư, kiểm EOF phải fail.
Trong bản thử ban đầu dùng fscanf liên tiếp, Icarus trả 0 trường ở lần đọc sau newline cuối và EOF đã bật. Bài đổi sang đọc theo dòng để tách rõ “không có dòng” với “có dòng nhưng parse sai”, thay vì coi mọi rc khác 3 là một EOF hợp lệ.
Điểm tổng quát là phải hiểu return value của đúng hàm và kiểm record count. Không dùng một vòng while chỉ nhìn feof rồi mặc định mọi lần đọc đều thành công. [3]
Expected đến từ file có nguồn độc lập
Ba phép tính trước chạy là 0+0=0,15+1=16 và 10+5=15. Carry được giữ bằng tổng 5 bit; record 15+1 bắt trường hợp vô tình chỉ giữ 4 bit làm tổng thành 0.
TB tự ghi file hằng số để ví dụ có thể chạy độc lập; đó không phải việc lấy output DUT để tự chấm. Ở flow thực, model phần mềm có thể tạo nhiều record, nhưng vẫn cần biết model và RTL có chia sẻ cùng lỗi thuật toán không.
Ba vector minh họa luồng I/O, không phải vét cạn bộ cộng 4 bit. Các bài A6 đã có kiểm vét cạn riêng; đừng nâng phạm vi bài này chỉ vì nó đọc từ file.
Dump đúng scope và đúng mục tiêu debug
Dumpfile đặt tên lesson.vcd, dumpvars chọn toàn hierarchy dưới DUT bằng mức 0. Đây là chọn scope ghi tín hiệu, không phải lệnh tự chứng minh waveform đúng. Để file gọn hơn, chọn tín hiệu hoặc độ sâu phù hợp câu hỏi debug.
Sau khi dữ liệu đã chạy, TB gọi dumpflush và kiểm VCD mở được, có ký tự mở đầu header như Icarus tạo. Mục đích là xác nhận có output để xem; kiểm prefix không chứng minh mọi timestamp hoặc lane đúng. [4]
Pipeline Icarus hiện chưa tích hợp trace extraction; example chỉ claim parsed/simulated, không claim traced. Những wave khác gắn origin simulated phải qua cơ chế đối chiếu riêng của dự án.
Ba record và một dòng malformed
Kỳ vọng trước chạy: ba tổng 0/16/15, mỗi dòng đủ 3 trường; sau ba dòng là EOF; malformed chỉ có 1 trường; VCD được tạo và checker kết thúc tại 3 ns.
Assertions kiểm dữ liệu và điều kiện nhập trước khi in summary. Runtime file nằm trong thư mục tạm; không commit vector sinh ra hoặc VCD thay cho source/bằng chứng. [5]
Đừng gọi file tồn tại là trace đã xác minh
- Không kiểm descriptor 0 rồi dùng một handle mở thất bại.
- Đọc thiếu trường nhưng tái sử dụng biến của record trước.
- Coi mọi parse failure là EOF, làm bỏ qua malformed record.
- Chỉ kiểm tổng số dòng mà không so dữ liệu mỗi dòng.
- Không giữ carry khi đọc expected hoặc tính sum.
- Dump toàn chip khi chỉ cần một scope nhỏ.
- Coi VCD có header là đã đối chiếu waveform từng ô.
Tự kiểm tra
Kiểm cả đường dữ liệu lẫn đường nhập dữ liệu
Một vector chỉ được dùng sau khi mở file, đọc dòng và parse đều đạt hợp đồng. Xác nhận đủ record, EOF và lỗi định dạng trước khi diễn giải kết quả DUT.
Bài giữ draft/LRM needs-spec-check; file I/O và VCD được mô phỏng thật trong phạm vi nêu rõ.
Nguồn và mức độ đối chiếu
- Verilog File IO Operations — bản chụp trong resources.zip, Opening and closing files. Trích dẫn; nguồn đã đọc các mục liên quan.
- Verilog File IO Operations — bản chụp trong resources.zip, Reading a line. Trích dẫn; nguồn đã đọc các mục liên quan.
- Verilog File IO Operations — bản chụp trong resources.zip, Detecting EOF. Trích dẫn; nguồn đã đọc các mục liên quan.
- Verilog VCD Dump — bản chụp trong resources.zip, dumpfile và dumpvars. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thí nghiệm nguyên bản ex.a7.tb-io, Thí nghiệm nguyên bản. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, tb-io language and system task semantics. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Thí nghiệm nguyên bản ex.a7.tb-io, Source, assertions và verification.json của TB nguyên bản. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, File I/O; formatted input; EOF; VCD system tasks. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Verilog File IO Operations — bản chụp trong resources.zip, Opening and closing files; How to read files; Reading a line; Detecting EOF. Trích dẫn; nguồn đã đọc các mục liên quan.
- Verilog VCD Dump — bản chụp trong resources.zip, $dumpfile; $dumpvars. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thí nghiệm nguyên bản ex.a7.tb-io, tb_files.sv và verification.json. Trích dẫn; nguồn đã đọc toàn văn.