Package và $unit: dùng chung định nghĩa mà không nhầm scope

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

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.

Thí nghiệm packages-unit

Tính trước:256byteparity128odd; localwidth 4 shadowwildcardpackageconstant 8 nhưng payload_t vẫn 8, otherpkg 3,$unitnibble4/31 truncate 15.

00_format_pkg.sv testbench
`timescale 1ns/1pspackage format_pkg;  parameter int PAYLOAD_W=8;  typedef bit[PAYLOAD_W-1:0] payload_t;  function automatic bit parity(input payload_t data);    return ^data;  endfunctionendpackagepackage audit_pkg;  parameter int PAYLOAD_W=3;endpackage
tb_package.sv testbench
`timescale 1ns/1pstypedef bit[3:0] unit_nibble_t;module tb_package;  import format_pkg::*;  localparam int PAYLOAD_W=4;  payload_t data;  $unit::unit_nibble_t nibble;  int n,k,ones,odd=0;  initial begin    if(PAYLOAD_W!=4||format_pkg::PAYLOAD_W!=8||audit_pkg::PAYLOAD_W!=3||$bits(data)!=8||$bits(nibble)!=4)      $fatal(1,"package/local/unit scope mismatch");    for(n=0;n<256;n++)begin      data=payload_t'(n);ones=0;      for(k=0;k<8;k++)ones+=(n/(2**k))%2;      if(int'(format_pkg::parity(data))!=ones%2||int'(data)!=n)$fatal(1,"package function n=%0d",n);      odd+=int'(format_pkg::parity(data));    end    nibble=unit_nibble_t'(31);    if(odd!=128||nibble!=15)$fatal(1,"package/unit final values");    $display("PACKAGE CHECK vectors=256 odd=128 local_w=4 package_w=8 other_w=3 unit_bits=4 last=255");    $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: PACKAGE CHECK vectors=256 odd=128 local_w=4 package_w=8 other_w=3 unit_bits=4 last=255

Chỉ packageconstants/type/parity và localshadow trong filelist này; $unit typedef cùng file TB. Không claim mọi compilation-unit grouping, transitive import, mutable package state 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.

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

Tự kiểm tra: packages-unit

  1. Local PAYLOAD_W4, payload_t từ format_pkg8: data rộng bao nhiêu?
  2. Local/package/other constant trong TB lần lượt bao nhiêu?
  3. $unit typedef trong example được đặt ở đâu để tránh suy cross-file?
  4. Trong 256 byte, số byte có parity odd là bao nhiêu?
  5. Import khác include ở điểm nào trong bài?

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

  1. 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.
  2. 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.
  3. 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ở).
  4. 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.
  5. 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ở).
  6. 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.