Timing control: lấy dữ liệu lúc nào, cập nhật lúc nào?
Tiên quyết
- Module A6: Verilog cấu trúc: Đang tải
- Initial, always và fork: đọc nhiều process cùng chạy: Đang tải
Sau bài này bạn sẽ
- Dự đoán sự khác nhau giữa #3 q=d và q=#3 d
- Phân biệt chặn process với lên lịch cập nhật nonblocking
- Đọc wait, event và repeat theo các mốc đã kiểm
- Dùng phản ví dụ để tránh hiểu #0 là cách chờ NBA chung
Ba câu hỏi cho một assignment có delay
Đừng chỉ hỏi “có #3 thì output đổi sau ba đơn vị phải không?”. Cần tách ba thời điểm: lấy giá trị RHS, cập nhật LHS và cho process chạy statement tiếp theo.
TB bắt đầu source=0, đổi thành 1 tại t=1 ns rồi giữ. Ba phép gán đều có delay 3 nhưng không lấy cùng dữ liệu và không chặn writer cùng cách. Ta dùng các process riêng, mỗi process ghi biến riêng, và kiểm tổng kết ở t=4 để tránh sample trùng các update ở t=3.
Nguồn đào tạo cung cấp cách phân nhóm và ví dụ để đối chiếu; các con số dưới đây từ chương trình nguyên bản đã chạy. Quy tắc scheduling đầy đủ vẫn [1].
Delay trước statement: đợi rồi mới lấy RHS
Với #3; inter_value=source;, process chờ ba ns trước, sau đó mới đọc source. Source đã bằng 1 từ t=1, nên inter_value nhận 1 tại t=3.
Đó là ý tưởng của inter-assignment delay trong ví dụ: delay đứng trước lúc statement gán được thực hiện. Không được lấy source=0 ở t=0 rồi giữ nó cho phép gán này, vì process chưa tới chỗ đọc RHS.
Đọc các nguồn web, luôn xác định delay tính từ lúc nào. Nếu statement nằm sau một lần chờ khác trong cùng process, mốc bắt đầu không còn là t=0. [2]
Delay trong assignment: lấy trước, ghi sau
Với intra_value = #3 source, process đi tới phép gán tại t=0 và lấy source=0 ngay lúc đó. Nó chờ tới t=3 rồi ghi giá trị đã lấy là 0, dù source ngoài kia đã thành 1.
Một mô hình suy nghĩ hữu ích là có một giá trị tạm được giữ cho phép gán này. Đừng vẽ một đường “source thay đổi thì kết quả đang chờ cũng đổi theo”, vì điều đó không khớp thí nghiệm đã chạy.
Source thay ở t=1 giúp phân biệt rõ hai cách đặt delay: inter=1, intra=0. Nếu source không đổi trong khoảng chờ, cả hai có thể cùng giá trị và bạn sẽ bỏ lỡ khác biệt ngữ nghĩa.
Cùng ghi ở t 3, process có thể tiếp tục khác lúc
nba_value <= #3 source cũng lấy source=0 tại t=0 và lên lịch ghi 0 cho t=3. Nhưng process không phải đứng chờ ba ns ở statement đó; câu tiếp theo ghi lại nba_done=0.
Ở phép blocking intra delay, statement sau chỉ chạy khi phép gán hoàn tất; vì vậy block_done=3. TB kiểm cả dữ liệu và hai mốc writer: nếu chỉ nhìn LHS ở t=4, bạn sẽ thấy intra và NBA cùng là 0 mà chưa hiểu cách chúng ảnh hưởng phần còn lại của process.
Bài không kiểm nhiều NBA ghi cùng biến hoặc đầy đủ các vùng event. Chỉ khẳng định cách capture và resume của đúng các statement đã viết. [3]
Wait, cạnh event và repeat không phải một kiểu chờ
Ba process quan sát các điều kiện khác nhau:
wait(source==1)hoàn tất ở t=1, khi điều kiện level trở thành đúng trong TB.@(posedge trigger)hoàn tất ở t=2, khi trigger đổi từ 0 lên 1.repeat(2) @(posedge clk)chờ hai cạnh lên của clock toggle mỗi 1 ns: các cạnh tại 1 và 3, nên hoàn tất ở t=3.
Một level đã đúng và một event đã xảy ra không phải cùng loại thông tin. Bài chỉ bố trí các waiter trước những thay đổi cần quan sát; chưa kiểm tình huống đăng ký event sau khi cạnh đã qua hoặc wait với điều kiện X/Z.
Đây là phần phân biệt để đọc TB, không phải khuyên đổi mọi event thành wait hoặc thêm một repeat tùy ý. [4]
#0 không có nghĩa chờ NBA hoàn tất
Một mô tả ngắn kiểu “#0 tránh race” cần được đặt trong quan hệ lịch cụ thể. Nó không bảo đảm rằng mọi nonblocking update trước đó đã xong.
TB có phản ví dụ nhỏ: cùng process thực hiện after_zero <= 1, rồi #0; zero_sample=after_zero. Biến after_zero ban đầu bằng 0. Kết quả kiểm sau đó là zero_sample=0, còn after_zero đã thành 1. Vậy #0 đã không làm phép đọc này chờ giá trị NBA mới.
Output thật ZERO RESULT sampled=0 after_nba=1 được assertion kiểm trước khi in. Phần Quick Check của nguồn ChipVerify cũng lưu ý giới hạn #0 với NBA; bài dùng TB độc lập để đối chiếu, không sao chép khuyến nghị chờ tùy ý thành coding rule. [5]
Kiểm các mốc 0, 1, 2, 3 và 4 ns
Tính trước khi chạy: source 0 ởt 0, source 1 từt 1; inter lấy 1 ởt 3, intra/NBA giữ 0 từt 0. Writer blocking tiếp tục ở 3, writer NBA ở 0. Wait/event/repeat lần lượt 1/2/3. Tổng kết ở 4, sau các cập nhật đang thử.
Ở t=2, TB còn kiểm cả ba LHS vẫn X, writer blocking chưa tiếp tục và writer NBA đã tiếp tục. Điều đó bắt lỗi cập nhật sớm hoặc vô tình chặn writer NBA. Ởt 4 nó kiểm mọi giá trị/mốc và phản ví dụ #0.
Parse và simulation Icarus đạt; không claim synthesis, trace hay timing silicon. [6]
Đặt delay để hiểu mô hình, không để che race
- Thấy #3 ở hai chỗ rồi cho rằng chúng lấy cùng RHS.
- Chỉ kiểm dữ liệu cuối mà không kiểm process tiếp tục khi nào.
- Coi #0 là rào đồng bộ chờ tất cả NBA.
- Coi event là một cờ level được giữ cho người tới sau.
- Nhầm delay giữa lần đảo clock với period rồi đếm sai repeat.
- Thêm delay vào RTL/TB để hết lỗi nhất thời rồi suy ra đã đúng mọi lịch chạy.
- Coi một ví dụ website là bằng chứng synthesis; flow hiện tại chỉ chạy TB mô phỏng.
Tự kiểm tra
Tách thời điểm capture, update và resume
Vẽ ba mốc đó cho từng statement trước khi ghép nhiều process. Chọn một stimulus đổi trong khoảng chờ để làm lộ khác biệt và kiểm cả trước lẫn sau thời điểm cập nhật.
Các kết quả này xác nhận thí nghiệm đã chạy, không thay cho toàn bộ LRM hoặc mọi wait/event/delay variant. Bài giữ draft/needs-spec-check dù đã có nguồn đào tạo được đọc và code tự kiểm.
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ở).
- Verilog Inter and Intra Assignment Delay — bản chụp trong resources.zip, Inter-assignment delay. Trích dẫn; nguồn đã đọc các mục liên quan.
- Verilog Inter and Intra Assignment Delay — bản chụp trong resources.zip, Blocking/nonblocking intra delay. Trích dẫn; nguồn đã đọc các mục liên quan.
- Procedural timing control — bản chụp trong resources.zip, Phân loại timing control trong nguồn đào tạo. Trích dẫn; nguồn đã đọc các mục liên quan.
- Verilog Inter and Intra Assignment Delay — bản chụp trong resources.zip, Quick Check #0. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thử nghiệm nguyên bản ex.a7.timing-ctrl, Bằng chứng thực nghiệm. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, Timing controls; inter/intra-assignment delays; wait/event controls; nonblocking assignments. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Thử nghiệm nguyên bản ex.a7.timing-ctrl, TB nguyên bản và verification.json đã chạy. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, Timing controls; inter/intra-assignment delays; wait/event controls; nonblocking assignment scheduling. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Verilog Inter and Intra Assignment Delay — bản chụp trong resources.zip, Inter/Intra-assignment Delays; Blocking vs Nonblocking Intra-assignment Delays; Quick Check #0. Trích dẫn; nguồn đã đọc các mục liên quan.
- Procedural timing control — bản chụp trong resources.zip, Delay timing control; Event timing control. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thử nghiệm nguyên bản ex.a7.timing-ctrl, content/code/ex.a7.timing-ctrl/verification.json và tb_timing.sv. Trích dẫn; nguồn đã đọc toàn văn.