Gate, dataflow và behavioral: khi nào ba mô tả tương đương?
Tiên quyết
- Module A2: Logic tổ hợp: Đang tải
- Module A4: Tuần tự & timing: Đang tải
- Module và instance: nối hai bộ cộng mà không nhầm cổng: Đang tải
- Net và variable: ai drive tín hiệu, ai giữ giá trị?: Đang tải
Sau bài này bạn sẽ
- Đọc ba cách mô tả cùng mux và suy luận logic tổ hợp
- Phân biệt tương đương trên 0/1 với hành vi khi có X
- Giải thích delay inertial của mô hình gate đã chạy
- Tách delay simulation khỏi timing và mapping phần cứng
Cùng chọn một trong hai input
Mux của bài chọn a khi sel=0, chọn b khi sel=1. Nếu chỉ nhìn bảng chân trị nhị phân, ta có thể mô tả nó bằng toán tử điều kiện, process tổ hợp hoặc các primitive NOT/AND/OR.
Câu hỏi kỹ thuật không chỉ là “ba code có chạy được không?” mà là tương đương trong miền nào, ở thời điểm nào. Ta kiểm tám tổ hợp 0/1, rồi chủ động đưa X vào select để thấy giới hạn của kết luận. Các quy tắc ngôn ngữ tổng quát vẫn [1].
Ba cách viết, ba mức mô tả
mux_dataflow dùng continuous assignment assign y = sel ? b : a. Dòng này mô tả quan hệ dữ liệu giữa input và output, không phải lệnh “chạy một lần”.
mux_behavioral dùng always @*, gán mặc định y=a rồi đổi thành b khi if(sel) đúng. Process mô tả cách tính output khi input liên quan thay đổi.
mux_gate ghép NOT cho select, hai AND và một OR. Với input 0/1, biểu thức Boolean là (a & ~sel) | (b & sel). Primitive gate thể hiện cấu trúc logic rõ hơn, nhưng không tự quyết định vị trí, kích thước transistor hay delay thực.
Ba module độc lập nằm trong cùng file, vì vậy Verilator lint báo MULTITOP dự kiến. Metadata ghi đúng warning này và vẫn yêu cầu không có warning mới ngoài tập đã khai báo. Không tắt lint để che vấn đề.
Behavioral không đồng nghĩa tuần tự
Process của ví dụ không có cạnh clock và gán y đầy đủ mỗi lần chạy. Khi sel bằng 0, y nhận a; khi sel bằng 1, y nhận b. Không có nhánh nhị phân nào cần nhớ y trước đó.
Nếu bỏ dòng gán mặc định và chỉ viết if(sel) y=b, yêu cầu đã đổi: khi sel không đúng, y giữ giá trị trước trong mô hình process. Không thể gọi đoạn đó là mux tổ hợp hoàn chỉnh chỉ vì nó vẫn nằm trong always @*.
Bài không đưa biến thể thiếu gán này vào evidence để tuyên bố đã kiểm latch. Hãy dùng lint/synthesis và bài latch riêng khi phân tích nó. Phần đã kiểm ở đây là ba top đúng như source được nhúng bên dưới.
Kiểm tám tổ hợp 0/1 và các top synthesis
Có ba input một bit nên cần tám tổ hợp nhị phân. TB tính expected bằng số nguyên từ bit sel, b và a; so cả ba output rồi mới tăng số case.
Yosys generic chạy riêng từng top và khớp 0 FF cho cả ba. Đây là kiểm tra không có thanh ghi trong các top cụ thể, không phải bằng chứng mọi netlist giống từng cổng hoặc đạt cùng timing. Parser kiểm cả RTL/TB; lint chỉ RTL; Icarus chạy các phép thử 4-state và delay. [2]
Select X làm lộ khác biệt
Trường hợp đầu: a=b=1, sel=X. Dataflow dùng ternary giữ bit bằng nhau giữa hai nhánh nên ra 1. Behavioral đã gán y=a=1; điều kiện if X không chọn nhánh b nên cũng ra 1. Mạch primitive tính 1 & X ở cả hai nhánh rồi OR, nên ra X.
Trường hợp thứ hai: a=0, b=1, sel=X. Dataflow không biết chọn bit nào nên ra X. Behavioral đi nhánh mặc định a nên ra 0. Gate cũng ra X. Output thật lần lượt là XSELECT RESULT dataflow=1 behavioral=1 gate=x và XBRANCH RESULT dataflow=x behavioral=0 gate=x.
Đây là ví dụ X optimism ở cách viết if: output xác định hơn trong mô hình không có nghĩa phần cứng thật biết select là gì. Cũng không suy ra một X của gate model luôn là lỗi vật lý. Cần xem mục đích simulation và hợp đồng thiết kế, không chỉ chọn cách viết có ít X nhất.
Một xung ngắn qua gate delay 2 ns
TB có một primitive riêng buf #2, với đơn vị thời gian 1 ns. Delay này chỉ nằm ở TB, không nằm trong file RTL đem synthesis.
Sau khi input 0 đủ lâu để output ổn định 0, TB đưa input lên 1 trong 1 ns rồi kéo về 0. Xung ngắn hơn delay 2 ns bị lọc trong mô hình inertial đã chạy. TB không chỉ nhìn một mẫu cuối: bộ đếm cạnh lên xác nhận chưa có cạnh lên output trong phép thử xung ngắn.
Sau đó input được giữ 1. Một ns sau, output vẫn 0; sau khi đã qua 2 ns, output là 1 và tổng số cạnh lên bằng 1. Dòng DELAY EVENTS rises=1 được in sau các assertion. Không áp dụng kết luận này cho mọi kiểu delay, mọi độ rộng xung hoặc mọi rise/fall delay khác nhau.
Synthesis không xác nhận delay vật lý
Ba top RTL không chứa #delay. Delay primitive chỉ là mô hình simulator do tác giả chọn. Flow Yosys generic không có thư viện timing, placement/routing hoặc STA; kết quả 0 FF không chứng minh mux có delay 2 ns trên chip.
Khi cần timing thật, phải có target, constraint và báo cáo tương ứng. Cũng không thêm #2 vào RTL sản phẩm rồi xem đó là cách bảo đảm timing. Khả năng tổng hợp cú pháp delay và cách tool xử lý cần xem tài liệu tool/flow cụ thể.
Lỗi khi đổi mức mô tả
- Đổi
?:sang if rồi suy ra tương đương cả khi có X. - Bỏ default assignment vì đã có
always @*và không kiểm nhánh giữ giá trị. - Thấy gate model có cấu trúc NOT/AND/OR rồi suy ra physical cell mapping không đổi.
- Dùng test 2-state để kết luận về X optimism.
- Chỉ kiểm output xung ngắn ở một thời điểm, bỏ sót cạnh/glitch đã xảy ra trước đó.
- Trộn delay TB vào file RTL synthesis rồi gọi báo cáo cell là báo cáo timing.
Tự kiểm tra
Nói rõ miền tương đương
Ba cách mô tả khớp tám input nhị phân; hai vector select X đã cho khác biệt cụ thể. Delay #2 có kiểm xung ngắn và xung giữ đủ lâu, chỉ trong mô hình TB.
Khi review, ghi rõ tập input, cách xử lý unknown, thời điểm sample và flow synthesis. Chưa dùng các phép thử này để khẳng định tương đương hình thức, timing/PPA hoặc đầy đủ mọi quy tắc delay của LRM.
Nguồn và mức độ đối chiếu
- IEEE 1800-2023 SystemVerilog LRM, cần đối chiếu LRM. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Thử nghiệm A6.levels: source và verification.json, Bằng chứng ba mức mô tả. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, Gate primitives, continuous and procedural assignments, delays. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Thử nghiệm A6.levels: source và verification.json, Ví dụ đã chạy: source và verification.json. Trích dẫn; nguồn đã đọc toàn văn.
- Thử nghiệm A6.levels: source và verification.json, mux_forms.sv, tb_levels.sv và verification.json. Trích dẫn; nguồn đã đọc toàn văn.