Đối với logic tổ hợp, if
/ else
được triển khai dưới dạng bộ ghép kênh 2: 1. Trong đại số Boolean, đây sẽ là:
Q = (A * S) + (B * S')
Ở đâu:
S
là đầu vào được cung cấp bởi if
điều kiện,
A
là đầu vào được cung cấp bởi then
biểu thức con
B
là đầu vào được cung cấp bởi else
biểu thức con và
Q
là đầu ra của biểu thức.
Về mặt lý thuyết, bạn có thể khái quát hóa điều này để bao gồm một cạnh đồng hồ duy nhất , nhưng nó phức tạp hơn rất nhiều và sẽ giống với một tế bào đồ họa khi bạn hoàn thành. Về cơ bản, nếu bao gồm một cạnh đồng hồ, bạn không thể có một else
mệnh đề (vì nó hoàn toàn "không thay đổi đầu ra") và bất kỳ phần không có cạnh nào của if
điều kiện sẽ đơn giản trở thành biểu thức kích hoạt đồng hồ. Khi bụi đã lắng xuống, bạn sẽ được để lại một phiên bản ít rõ ràng hơn của always_ff
câu lệnh mà bạn nên sử dụng thay thế.
Điều kiện có hai hoặc nhiều cạnh đồng hồ không thể tổng hợp.
EDIT: Đầu tiên, tôi không chắc if(posedge(...))
là có thể tổng hợp được. Nói chung, bạn sử dụng posedge(...)
mệnh đề trong always_ff @(...)
dòng và không cần posedge()
bên trong khối.
Trong SystemVerilog, hình thức chung của bộ ghép kênh 2: 1 là một if
câu lệnh. Ví dụ:
always_comb begin
if(S)
Q = A;
else
Q = B;
end
Tuy nhiên, nếu có cạnh đồng hồ, bạn cần sử dụng flip-flop:
always_ff @(posedge CLK) begin
if(CLK_ENA)
Q <= D;
end
Thêm một thiết lập lại không đồng bộ trông như thế này:
always_ff @(posedge RESET, posedge CLK) begin
if(RESET)
Q <= '0;
else if(CLK_ENA)
Q <= D;
end
Trong trường hợp này, RESET hoạt động ở mức cao. Lưu ý rằng bạn chỉ cần nói RESET là phần nhạy cảm trong @()
phần. Trong phần còn lại của khối, RESET sẽ có cấp độ sau cạnh. Cũng lưu ý rằng độ nhạy cảm cạnh là một danh sách; bạn không thể nói "và". (Trong Verilog gốc, bạn tách biệt độ nhạy cảm cạnh bằng "hoặc", khiến mọi người hiểu lầm "và" cũng có thể hoạt động tốt.)