Tác giả: TrongTran
Ngày: 12/09/2019.
Cập nhật: 14/10/2019.
Cập nhật: 14/10/2019.
Trong đợt cập nhật trước thì mình đề cập đây là một lỗi syntax. Tuy nhiên, Có một anh đã góp ý cho mình rằng đây không phải là một lỗi syntax. Việc design như thế này là không gây ra lỗi. Tuy nhiên, chúng ta không khuyến khích design theo cách này. Vì logic out ra ngoài có thể không đúng với function. Mình đổi lại từ "lỗi" thành từ "vấn đề" để tránh nhầm lẫn (thật ra mình cũng không biết nên gọi bằng từ gì cho đúng).
Đây là một phương thức design mà một anh trong nhóm mình vô tình phát hiện khi tổng hợp gate từ verilog code.
Đây là một phương thức design mà một anh trong nhóm mình vô tình phát hiện khi tổng hợp gate từ verilog code.
Mình đã tiến hành kiểm nghiệm và thật ngạc nhiên là hầu hết
các tool verify hiện nay đều không thể phát hiện được. Thậm chí là cả VCS
(Synopsys), NCSIM (Cadence) và DC compiler (Tool tổng hợp gate từ
RTL). Nếu DC compiler không thể phát hiện đã đành đằng này ngay cả tool check
equivalent giữa gate và RTL cũng không thể phát hiện được (Formality).
Sau khi tiến hành kiểm tra thì mình phát hiện ra chỉ có 1
tool Spyglass của synopsys là có thể phát hiện được cách thiết kế này. Tuy nhiên, chúng ta thường bỏ qua những lỗi được report bởi tool này. Lí do là vì một design lớn thường xuất hiện cả trăm ngàn lỗi (Report bởi spyglass) và người confirm hầu như không thể phát hiện được lỗi nào là thật, lỗi nào có thể bỏ qua.
Đầu tiên mình nói đây là vấn đề liên quan đến việc chặp 2
output với nhau. Bạn sẽ nghĩ ngay đến một module như thế này:
module test (in_0, in_1, in_2, in_3, out);
input in_0;
input in_1;
input in_2;
input in_3;
output out;
wire out;
assign out = in_0&in_1;
assign out = in_2&in_3;
endmodule
Trường hợp trên ta có biến out được assign 2 lần.
Đây là một trường hợp phổ biến và chắc chắn là mọi tool đều
có thể phát hiện được.
Tuy nhiên, có một trường hợp khác, Ta xét ví dụ như bên dưới:
module test_spyglass (clk, rst_n, in_0, in_1, in_2, in_3,
out);
input clk;
input rst_n;
input in_0;
input in_1;
input in_2;
input in_3;
output out;
reg tmp_0;
reg tmp_1;
wire out;
always @(posedge
clk or negedge rst_n) begin
if (!rst_n)
begin
tmp_0 = 1'b0;
end else begin
tmp_0 <=
in_0;
end
end
always @(posedge
clk or negedge rst_n) begin
if (!rst_n)
begin
tmp_1 = 1'b0;
end else begin
tmp_1 <=
in_1;
end
end
module_and_logic
module_and_logic_00 (.in_0(in_2), .in_1(tmp_0), .out(out));
module_or_logic
module_or_logic_00 (.in_0(in_3), .in_1(tmp_1), .out(out));
endmodule
module module_and_logic (in_0, in_1, out);
input in_0;
input in_1;
output out;
assign out =
in_0&in_1;
endmodule
module module_or_logic (in_0, in_1, out);
input in_0;
input in_1;
output out;
assign out =
in_0|in_1;
endmodule
Cấu trúc của code này như sau:
Hai submodule được gọi và 2 submodule này đều out ra cùng 1
tín hiệu đó là “out”.
Chỉ khác nhau 1 điểm đó là với module bên trên tín hiệu output là từ 2 submodule, còn như ví dụ ban đầu output từ một combinational logic trong module top.
Khi tổng hợp code verilog này thành gate
nestlist, Ta sẽ có được 1 gate như sau:
module test_spyglass (clk, rst_n, in_0, in_1, in_2, in_3,
out);
input clk;
input rst_n;
input in_0;
input in_1;
input in_2;
input in_3;
output out;
reg tmp_0;
reg tmp_1;
wire out;
wire HINET_0, HINET_0;
DFF D0 ( .D(in_0), .CP(clk), .CDN(rst_n), .Q(tmp_0) );
DFF D1 ( .D(in_1), .CP(clk), .CDN(rst_n), .Q(tmp_1) );
module_and_logic
module_and_logic_00 (.in_0(in_2), .in_1(tmp_0), .out(HINET_1));
module_or_logic
module_or_logic_00 (.in_0(in_3), .in_1(tmp_1), .out(HINET_0));
AND (.A1(HINET_0), .A2(HINET_1), .Z(out) );
endmodule
module module_and_logic (in_0, in_1, out);
input in_0;
input in_1;
output out;
AND (.A1(in_0),
.A2(in_1), .Z(out) );
endmodule
module module_or_logic (in_0, in_1, out);
input in_0;
input in_1;
output out;
OR (.A1(in_0),
.A2(in_1), .Z(out) );
endmodule
Như vậy là ta có thêm 1 cổng logic AND (Phần màu đỏ) để “and” 2 tín hiệu
đó lại. Đây là lí do mà việc chạy để kiểm tra equivalence giữa RTL và gate lại
không phát hiện được. Đây cũng là lí do mình nói function của bạn có thể bị sai. Tại sao ư ? Nếu bạn chỉ verify cho RTL và bạn dùng tool Formality để check equivalence giữa gate và RTL. Bạn tin tưởng rằng RTL của bạn đúng và FM pass. Không có bất kì hành động nào nhằm verify function cho gate. Tuy nhiên, Vấn đề sẽ trở nên nghiêm trọng hơn với việc sai fucntion trên gate.
Mình ví dụ, Đây là 2 tín hiệu out error cho fusa từ 1 IP đến module interrupt.
Khi có error xảy ra nó sẽ toggle lên 1. Trong trường hợp chèn cổng AND. Tín hiệu chỉ toggle khi cả hai logic đều bằng 1. Điều này không đúng với mục đích function của chúng ta đó là interupt khi 1 trong 2 tín hiệu error toggle.
Mình ví dụ, Đây là 2 tín hiệu out error cho fusa từ 1 IP đến module interrupt.
Khi có error xảy ra nó sẽ toggle lên 1. Trong trường hợp chèn cổng AND. Tín hiệu chỉ toggle khi cả hai logic đều bằng 1. Điều này không đúng với mục đích function của chúng ta đó là interupt khi 1 trong 2 tín hiệu error toggle.
Tuy nhiên, Tool Spyglass của synopsys hoàn toàn có thể phát
hiện ra lỗi này và báo như sau “Non-tristate signal 'test_spyglass.out' has
multiple drivers”.
Như vậy, bạn cố gắn lưu ý cách design này để tránh nhé. Đặc biệt là
với các bạn thích dùng tool VCS để mô phỏng.
Mọi người để lại comment để góp ý với mình hen. Cảm ơn ạ.
No comments:
Post a Comment