Interface nâng cao: tham số, nhiều lane và kết nối theo tên
Tiên quyết
Sau bài này bạn sẽ
- Tách value parameter và type parameter tại elaboration
- Dùng genvar cho phần tử interface array, giữ từng lane độc lập
- Giải thích .name và .* qua các kết nối đã kiểm
Nhân bản lane không được nhân bản cả lỗi nối dây
Một bộ cộng 1 bit và một bank ba bộ cộng 3 bit có thể dùng chung cấu trúc interface. Khó khăn không nằm ở việc đổi một con số trong khai báo: output cần đủ carry, từng lane phải có instance riêng và checker phải phát hiện khi lane k vô tình đọc tín hiệu của lane 0.
Bài này ghép ba thí nghiệm: bank W=1/N=2, bank W=3/N=3 và module copy có type parameter là packed struct. Mỗi phần có số check và điều kiện kết thúc riêng. Chúng chạy song song; tổng số check là phép cộng, còn thời điểm kết thúc là thời gian của nhóm lâu nhất.
W là cấu hình elaboration của từng instance
sized_link #(.W(W)) links[N](); tạo N interface với input rộng W và total rộng W+1. W được chọn khi elaboration, không phải biến đổi từ 1 thành 3 giữa hai vòng lặp runtime. Hai group trong top tạo hai specialization cùng tồn tại.
Một parameter cùng tên ở module khác không tự đồng bộ theo interface. Main tránh khai báo thêm width riêng trong sum_bank: phép cộng lấy trực tiếp member của links[k] và thêm một bit 0 ở mỗi toán hạng. Nếu module có storage nội bộ phụ thuộc W, cần truyền hoặc suy ra kích thước đúng và kiểm consistency. Không lấy việc nối được port làm bằng chứng mọi width đã phù hợp.
Array interface là nhiều instance trong hierarchy
links[N]() gồm N instance, mỗi phần tử có a/b/total riêng. Đây khác với một logic vector chứa N giá trị. Tên links[0] chỉ đến một instance cụ thể trong hierarchy; không mặc định coi mọi cách index runtime của data array cũng dùng được cho interface array.
Main dùng for(genvar k=0;k<N;k++) để elaboration tạo kết nối và process từng lane. Trong mỗi bản sao, k là hằng. Ngược lại, probe dùng một biến int để chọn links[index].a bị pyslang từ chối. Nếu cần chọn đích ở runtime trong class, hãy xem cơ chế virtual interface thay vì thay genvar bằng int mà giữ nguyên truy cập hierarchy.
Dữ liệu từng lane phải phân biệt được lỗi alias
Ở mỗi lane k, a quét 0..D−1 và b được đặt bằng (b_loop+k) modulo D, với D=2^W. Phép dịch vòng theo k vẫn phủ toàn bộ cặp đầu vào cho từng lane, đồng thời tạo khác biệt giữa các lane tại cùng thời điểm.
Checker đối chiếu total với a_loop+(b_loop+k)%D. Không dùng lại links[k].b làm oracle, vì lỗi nối dây có thể khiến cả stimulus lẫn phép tự kiểm cùng đọc nhầm. Bản sao DUT dùng links[0].b cho mọi lane bị runtime checker bắt; không chỉ đếm đủ loop rồi gọi là functional coverage hoàn chỉnh.
Tên trùng là điều kiện kết nối, không phải suy đoán ý nghĩa
sum_bank #(.N(N)) dut(.links) viết tắt của .links(links). Formal links được nối với tên links ở scope instantiation. copy_word #(.T(Token)) dut(.*) nối data/result cùng tên trong type_group; hai cổng này được kiểm thực sự bằng mô phỏng.
.* không tìm một tín hiệu có ý nghĩa gần giống tên cổng, cũng không tự ghép field struct theo vị trí. Khi local signal có tên khác, dùng kết nối tường minh .data(source_word); khi review, mở declaration và scope để biết actual là gì. Bài không dùng bảng khái quát của tutorial về mọi port không match để suy rằng thiếu tên sẽ luôn im lặng; giữ warning/error của cấu hình tool thật.
Parameter type thay kiểu của cổng, không cấp phát object
Module copy_word khai báo parameter type T=logic[3:0], rồi có input T data và output T result. Override .T(Token) dùng packed struct gồm valid 1 bit và tag 3 bit. T là kiểu, không phải giá trị width; không truyền số 4 để thay cho tên kiểu Token.
Main quét đủ 16 bit-pattern của Token. Ngoài equality toàn word, checker kiểm valid bằng bit cao của số vòng lặp và tag bằng ba bit thấp, nên lỗi đảo bit không bị giấu sau một counter đúng. Đây là truyền một packed value; không phải deep clone object, không chứng minh mọi kiểu class/unpacked payload dùng được với mọi implementation.
216 phép kiểm nhưng chỉ 64 ns
Với W=1, mỗi lane có 2×2=4 cặp; hai lane cho 8 check. Với W=3, mỗi lane có 8×8=64 cặp; ba lane cho 192 check. Nhóm type có 16 pattern nên tổng là 8+192+16=216.
Các lane phát stimulus và chờ #1 song song. Nhóm nhỏ xong ở 4 ns, nhóm type ở 16 ns, nhóm rộng ở 64 ns. Top đợi cả ba done nên kết thúc ở 64 ns, không phải 84 hay 216 ns. Mỗi lane chỉ set done sau check cuối và group cộng lane_checks sau khi đủ done; đếm thời gian hay số process không thay cho phép đối chiếu chức năng.
Hai cấu hình width và một cấu hình type
Expected trước chạy: INTERFACE ADV CHECK widths=1,3 lanes=2,3 lane_checks=200 type_checks=16 total=216 time_ns=64. Parsed/simulated chỉ áp dụng source và tool đã ghi, không phải mọi width tùy ý hoặc bằng chứng tổng hợp.
Hai mutant đã giữ checker: đọc b của lane 0 cho các lane khác và đảo dữ liệu ở module copy. Probe runtime index là lỗi parser riêng. Khi thêm W=0 hoặc N=0, phải định nghĩa hợp đồng mới và kiểm tool, không suy từ hai cấu hình dương đã chạy.
Tự kiểm tra
Đếm specialization, instance rồi mới đếm dữ liệu
Khi debug một bank, kiểm W/N ở nơi tạo instance, mapping từng lane và formal/actual của .name hay .*. Sau đó so kiểu của module nhận dữ liệu và oracle của từng lane. Chạy lại biên nhỏ, dữ liệu phân biệt lane và điều kiện hoàn tất giúp tìm lỗi mà một ví dụ “compile được” chưa phát hiện.
Nguồn và mức độ đối chiếu
- SystemVerilog Interface Parameters — bản chụp resources.zip, Basic Syntax; Overriding the Default at Instantiation; Connecting a Parameterized Interface to a Design. Trích dẫn; nguồn đã đọc các mục liên quan.
- SystemVerilog Interface Array — bản chụp resources.zip, Declaring an Interface Array; Connecting Individual Array Elements to a Design. Trích dẫn; nguồn đã đọc các mục liên quan.
- SystemVerilog Implicit Port Connections — bản chụp resources.zip, The .name Shorthand; The .* Wildcard. Trích dẫn; nguồn đã đọc các mục liên quan.
- SystemVerilog Module Type Parameters — bản chụp resources.zip, Declaring a Type Parameter; Overriding a Type Parameter at Instantiation. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thí nghiệm nguyên bản ex.b4.interface-adv, Source, self-checks, verification.json và fault probes. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, Interfaces, modports, parameterization and virtual interfaces — chưa đối chiếu LRM. Chưa đối chiếu với văn bản nguồn (chưa mở).
- SystemVerilog Implicit Port Connections — bản chụp resources.zip, The `.name` Shorthand; The `.*` Wildcard. Trích dẫn; nguồn đã đọc các mục liên quan.