Package và $unit: dùng chung định nghĩa mà không nhầm scope
Tiên quyết
- Module B1: Data types: Đang tải
- Enum và typedef: tên kiểu không thay cho kiểm dữ liệu: Đang tải
Sau bài này bạn sẽ
- Chia sẻ type/function bằng package và qualifier rõ
- Phân biệt local shadow với sửa một định nghĩa package
- Giới hạn $unit theo compilation-unit grouping thay vì giả định mỗi file là một unit
Tên giống nhau không đồng nghĩa cùng định nghĩa
Testbench có local PAYLOAD_W4, format_pkg có 8 và audit_pkg có 3. Một tên unqualified có thể được tìm ở scope khác với điều người đọc nghĩ. Explicit namespace giúp review, nhưng vẫn cần kiểm type đã được định nghĩa ở đâu và khi nào.
Package đặt type và function vào namespace riêng
Format_pkg định nghĩa payload_t8bit và parity, audit_pkg giữ constant khác cùng tên. TB import từ format_pkg và gọi function bằng format_pkg::parity. Không chép lại typedef ở nhiều file rồi coi chúng luôn cùng type. [1]
Import không phải textual include
Trong ví dụ, package source được compile trước TB. Import làm tên được tìm thấy theo scope; nó không phải thao tác chèn text vào module như include. Kiểm compiler nhận đúng package có tên đầy đủ; import không phải cơ chế tự tìm source file trên đĩa.
Local width 4 không làm payload_t trở thành 4 bit
Local PAYLOAD_W4 thắng ở unqualified name của TB, nhưng payload_t đã được định nghĩa bằng package constant 8. Vì vậy $bits(data)=8, không phải 4. Explicit format_pkg::PAYLOAD_W vẫn 8 và audit_pkg::PAYLOAD_W là 3. Đây là case đã kiểm, không phải lời khuyên tạo nhiều shadow name trong code sản phẩm.
$unit là compilation-unit scope, không mặc định là mọi file
Unit_nibble_t khai ở ngoài module nhưng trong cùng source file với TB, và được dùng qua $unit::unit_nibble_t. Grouping compilation unit phụ thuộc cách compile; không dùng ví dụ cùng file để đảm bảo một global typedef ở file khác luôn nhìn thấy. Package được chia sẻ rõ ràng thường dễ quản lý hơn phụ thuộc $unit ngầm.
File order và build command vẫn là một phần của flow
Metadata liệt kê00_format_pkg trước tb_package, giữ dependency của package rõ. Không chữa lỗi missing package bằng import thêm tên sai hoặc đổi một kiểu khác cho đủ compile. Ghi đúng file list/include/import rồi kiểm trong flow thật, nhất là khi nhiều công cụ chia compilation units khác nhau.
Qualifier không thay kiểm width và dữ liệu
Payload 8 bit nhận đủ 0..255. Unit nibble 4 bit nhận 31 còn 15. Namespace không ngăn truncation hoặc thay đổi cast semantics; các bài B1 vẫn áp dụng. Main chỉ chia sẻ constants/type/pure function, không claim mutable global state, transitive imports hoặc synthesis mọi package construct.
256 parity và ba constant cùng tên
Expected trước chạy: 256 byte có 128 odd; local 4/package 8/other 3; payloadbits 8 và unitbits 4, value cuối 255.
Oracle parity dùng số học từng bit, khác reduction XOR của function; Verilator 2-state và parser đều đạt. [2]
Tự kiểm tra
Ghi rõ tên đến từ đâu
Dùng một định nghĩa chia sẻ, import có chủ ý và qualifier tại chỗ dễ nhầm. Kiểm width ở nơi định nghĩa type, không chỉ nhìn constant local. Bài giữ draft/LRM needs-spec-check và không suy mọi compilation-unit rule từ một file list.
Nguồn và mức độ đối chiếu
- SystemVerilog Package — bản chụp resources.zip, Package syntax và import. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thí nghiệm nguyên bản ex.b3.packages-unit, Bằng chứng. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, packages-unit procedural/package 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.b3.packages-unit, Source, self-checks, metadata, verification.json và mutation probes. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, packages-unit procedural semantics. Chưa đối chiếu với văn bản nguồn (chưa mở).
- SystemVerilog Package — bản chụp resources.zip, SystemVerilog Package Syntax; Importing a Package; Search Order: Why Local Always Wins. Trích dẫn; nguồn đã đọc các mục liên quan.