Always_comb, always_ff và always_latch: nói rõ phần cứng định mô tả
Tiên quyết
- Module B1: Data types: Đang tải
- Latch inference: đường không gán cũng mô tả phần cứng: Đang tải
Sau bài này bạn sẽ
- Phân biệt cập nhật tổ hợp, giữ theo level và lấy mẫu theo edge
- Kiểm reset đồng bộ trước và sau clock thay vì suy từ tên rst_n
- Tách intent keyword, quy tắc ngôn ngữ và mức enforcement của tool
Một input đổi, ba output không cần đổi giống nhau
Cùng a/b đi vào mux, một FF và một latch. Khi đổi a lúc không có cạnh clock và gate đóng, y tổ hợp có thể đổi ngay, q phải giữ theo FF, held phải giữ theo latch. Keyword giúp đọc ý định, còn waveform/checker phải chứng minh contract cụ thể ấy.
Always_comb cho mô tả tổ hợp đầy đủ
Ví dụ gán y theo sel ở mọi đường, không có trạng thái cần giữ. Không viết event list bằng tay. Bỏ một nhánh assignment không tự được keyword sửa thành một hàm đúng; tool có thể báo mismatch intent hoặc latch tùy flow. Ngôn ngữ còn có quy tắc về time-zero evaluation, function sensitivity và writer, nhưng bài chỉ claim các stimulus/check đã chạy. [1]
Always_ff vẫn cần event control đúng
Q dùng always_ff @(posedge clk) và NBA. Reset active-low nằm trong thân, nên đồng bộ: kéo rst_n0 giữa hai cạnh chưa làm q đổi ngay. Thêm negedge reset vào event control sẽ đổi contract thành async. Dùng NBA cho state là guideline tránh race ở đây; không nói keyword bắt buộc mọi assignment phải là NBA trong mọi ngữ cảnh.
Always_latch cho phép đường giữ có chủ ý
Held nhận a khi gate 1 và giữ khi gate 0. Không có reset latch trong ví dụ, nên ban đầu heldX. Đây là storage level-sensitive đã yêu cầu, khác thiếu else ngoài ý muốn trong always_comb. Không thêm default 0 nếu mục tiêu thật là giữ giá trị. [2]
Reset đồng bộ phải được kiểm trước cạnh
TB đặt rst_n0 nhưng chưa phát cạnh, q vẫnX trong Icarus; sau tick đầu q 0. Cuối testcase, q đange, kéo rst_n0 và kiểm nó vẫn e trước tick reset rồi mới về 0. Như vậy một mutant đổi sang async reset không thể pass chỉ nhờ cùng giá trị cuối.
Kiểm sau NBA và đổi stimulus ngoài cạnh
Task tick phát cạnh rồi đợi 1 ns mới so q. Các thay đổi control/data được thực hiện khi clk 0, nên không tạo race driver/checker với FF ở cùng Active event. Phân biệt ý định RTL với vị trí sample trong TB; cùng keyword đúng nhưng TB sample sớm vẫn có thể kết luận sai.
Keyword không thay review ownership và reset
Mỗi output ở đây có một procedural owner rõ. Không suy từ một lượt lint sạch rằng mọi tool đều từ chối tất cả kiểu multiple writers hoặc sensitivity/function corner case. Các rule chính thức còn needs-spec-check; điều đã kiểm là hành vi mux/latch/FF và cell count của chính source này.
Năm tick và ba cách giữ dữ liệu
Expected tính trước: reset/capture 5/capture 9/capturee/reset, tổng 5 tick; y cuối e, held giữ 5, q cuối 0 và q ban đầuX.
Parse/lint/Icarus/Yosys đạt; generic 4 FF và 4 latch, không phải PPA/STA hoặc bảo đảm reset silicon. [3]
Tự kiểm tra
Chốt thời điểm nào output được phép đổi
Dùng keyword để diễn đạt intent, event control để diễn đạt clock/reset, assignment coverage để diễn đạt storage. Sau đó kiểm cả thời điểm output phải đổi lẫn thời điểm nó phải giữ. Bài vẫn draft/LRM needs-spec-check.
Nguồn và mức độ đối chiếu
- SystemVerilog always\_comb, always\_ff — bản chụp resources.zip, Intent và syntax. Trích dẫn; nguồn đã đọc các mục liên quan.
- SystemVerilog always\_comb, always\_ff — bản chụp resources.zip, Latch intent. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thí nghiệm nguyên bản ex.b3.always-x, Bằng chứng. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, always-x procedural 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.always-x, Source, self-checks, metadata, verification.json và mutation probes. Trích dẫn; nguồn đã đọc toàn văn.
- SystemVerilog always\_comb, always\_ff — bản chụp resources.zip, Syntax; always_comb; always_latch; always_ff. Trích dẫn; nguồn đã đọc các mục liên quan.