Tuesday, December 31, 2019

Cách tính BW và latency trong 1 hệ thống SoC sử dụng chuẩn giao tiếp AXI protocol

Tác giả: TrongTran
Ngày: 31/12/2019

Nếu bạn nào đang làm về verification cho system performance (ST) thì bài này sẽ bổ ích cho bạn.

Ngày nay performance quyết định một phần rất quan trọng trong một hệ thống SoC nhắm giúp sản phẩm có thể cạnh tranh trên thị trường.

Việc verification hiện tại không chỉ đơn thuần là kiểm tra function của hệ thống mà còn kiểm tra performance của hệ thống. Nghĩa là một hệ thống chạy đúng là chưa đủ mà phải còn chạy nhanh. Mình lấy ví dụ:

Khi bạn sử dụng 3G và 4G thì đâu là sự khác biệt. Bạn không chỉ quan tâm tới sự ổn định của mạng, ít bị lỗi, bảo mật mà còn quan tâm đến tốc độ mạng.

Vì vậy performance đóng một vai trò cực kì quan trọng trong hệ thống SoC.

Hai yếu tố quan trọng nhất để đánh giá performance của hệ thống đó là Bw (Bandwidth) và latency (Độ trễ).

1. Cách tính BW.

Nhiều tài liệu định nghĩa là BW (bandwidth) là số lượng transaction được transfer trong 1 hệ thống trên một đơn vị thời gian.

Tuy nhiên, Theo mình cái này cần làm rõ lại, Giả sử mình có 1 hệ thống SoC gửi và nhận data với chuẩn AXI protocol.

Mình tiến hành đo đạc và thử nghiệm và dưới đây là kết quả:


(ARLEN)Length = 16
(ARLEN)Length = 1
Số lượng transaction kênh AR
690
1113
Số lượng transaction kênh R
16*690 =11040
1*1113 = 1113
BW
3532.8 Mb/s
356.16 Mb/s
Thời gian chạy
50 us
50 us


Như vậy BW không phụ thuộc vào số lượng transaction kênh AR/AW mà phụ thuộc vào kênh W/R.


(ARLEN)Length = 16
(ARLEN)Length = 16
ARSIZE
32 bytes
16 bytes
Số lượng transaction kênh AR
690
690
Số lượng transaction kênh R
16*690 =11040
16*690 = 11040
BW
3532.8 Mb/s
1766.4 Mb/s
Thời gian chạy
50 us
50 us


BW còn phụ thuộc vào tín hiệu ARSIZE/AWSIZE nghĩa là số lượng byte được transfer trong 1 transaction.

Tóm lại để tính toán được BW chúng ta cần biết các thông tin sau:

B: số byte transfer trong 1 transaction được tính từ ARSIZE/AWSIZE.

T: Run time

N: Số lượng transaction kênh W/R được transfer trong khoảng thời gian “run time”.



Như vậy công thức tính BW sẽ là:

BW = B*N/T 

Đơn vị đo lường BW thường là MB/s hoặc GB/s

Ví dụ:

Mình có master A có các thông số sau:

  • ARSIZE = 4 word (1 word = 32 bit)
  • Số lượng transaction kênh AR = 690 transaction
  • ARLEN = 16
  • Run time = 50 ns


Như vậy ta tính được số transaction kênh R là = 690*16 = 11040 transaction.

Số bit được transfer trong 1 transaction là 4*32 = 128 bit.

Tống số data transfer là 128*11040 = 1413120 bit = 176640 byte = 176.64 KB = 0.17664 MB.

Run time = 50 ns = 0.00005 s.

Vậy BW = 0.17664/0.00005 = 3532.8 MB/s.


Lưu ý:
  • Trong tính toàn BW thì 1MB = 1000KB = 1000000 B.
  • 1 Byte = 8 bit.
  • Gửi transaction với single burst (1 beat) thì BW thấp.
  • Gửi transaction với multi burst (> 1 beat) thì BW cao hơn.
  • Nguyên nhân là do cùng 1 lượng data nhưng với single burst thì cần gửi nhiều tín hiệu control hơn.
  • Cùng số lượng transaction, Data width càng lớn thì BW càng lớn.
  • Cùng số lượng transaction, Data width càng nhỏ thì BW càng nhỏ.



Để đánh giá BW cảu hệ thống chúng ta cần quan tâm đến 3 yếu tố:

  • BW của master : Được tính tại A (Cho master A) hoặc B (Cho master B) hoặc tại C (Cho master C).
  • BW của bus system: bằng tống BW của A + B + C. Lưu ý là BW tối đa của bus system phải lớn hơn tổng các BW của các master gửi tới nó thì hệ thống mới đạ yêu cầu.
  • BW của slave (hoặc DDR): Được tính toán tại D.

2. Cách tính latency.

Chúng ta cần phân biệt các khái niệm sau:

  • Write latency
  • Write data latency
  • Read latency

Write data latency



Khoảng thời gian được tính từ sau khi AWVALID & AWREADY = 1 (handshake kênh write address ) cho đến khi WVALID & WREADY & WLAST = 1.


Write latency



Khoảng thời gian được tính từ sau khi AWVALID & AWREADY = 1 (handshake kênh write address ) cho đến khi BVALID & BREADY & BLAST = 1.

Ta luôn có Write latency > Write data latency.



Read latency




Khoảng thời gian được tính từ sau khi ARVALID & ARREADY = 1 (Handshake kênh Read address) cho đến khi RVALID & RREADY & RLAST = 1.



Early response for B channel






BVALID sẽ assert và gửi về slave ngay WVALID & WREADY = 1

Nếu checker đặt tại A thì write latency sẽ nhỏ hơn thực tế


Lưu ý:

  • Gửi transaction với random address thì latency sẽ lớn hơn
  • Gửi transaction với sequential address thì latency sẽ nhỏ
  • Chú ý tới các fifo trong design nó sẽ ảnh hưởng đến latency trong hệ thống.

Bây giờ xét trường hợp ngược lại. giả sử ta có được số latency trung bình của một transaction. Ta có thể tính được run time cần để transafer một số lượng transaction cụ thể không ?

Xét bài toán bên dưới:

  • Latency time của 1 transaction L = 500ns
  • ARLEN = 1
  • Số transaction cần transfer N = 20 transaction.
  • Số OS (Outstanding của bus system) OS = 4.

Như vậy thời gian để hệ thống transfer 20 transaction trên là:



T = 5 x 500ns + 7 x ACLK.

ACLK : là chu kì clock.

Nếu chu kì clock là nhỏ so với latency ta có công thức gần đúng là

T = 5*500ns.

Monday, December 23, 2019

Giải đáp vài thắc mắc về AXI protocol


Biên dịch và soạn thảo: TrongTran
Ngày: 23/12/2019


Tài liệu tham khảo: https://community.arm.com/

Mình không giải thích lại về chuẩn giao tiếp AXI. Bạn nào chưa biết thì có thể tham khảo các bài viết của anh Quân Nguyễn tại trang này nhé:

http://nguyenquanicd.blogspot.com/2018/08/busbai-1-giao-thuc-amba-axi.html



Trong bài này mình sẽ giải thích một số điểm corner case trong chuẩn AMBA AXI protocol . Đây cũng là những câu hỏi của hầu hết các diễn đàng ARM trên thế giới mà mình thu thập lại trong quá trình đào sâu về AXI protocol.


Câu 1: WVALID và WREADY có thể được assert trước AWVALID và AWREADY tại phía slave không, Như vậy có violate AXI protocol ? 

Câu trả lời là có. Như chúng ta đã biết để tăng performance cho hệ thống, ARM đã phân chia kênh AW, W và B độc lập nhau như vậy trên đường truyền từ master tới slave qua interconnect (BUS system) thì kênh AW có thể qua nhiều register hơn kênh W. Do đó, kênh AW sẽ bị delay và có thể đến slave sau kênh W.

Mình lấy ví dụ:

Master assert kênh AW trước kênh W một chu kì xung clock. Nhưng kênh AW đi qua 4 flip flop còn kênh W đi qua 2 flip flop lúc này kênh W sẽ đến slave trước kênh AW.



Điều này không violate AXI protocol. Tuy nhiên, xét về mặt hệ thống, việc có chấp nhận điều này (WVALID assert trước AWVALID) hay không là phụ thuộc vào slave. Nếu slave không chấp nhận thì người design interconnect phải sữa lại design để đảm bảo delay giữa hai channel thoã mãn điều kiện. Đặc biệt, Nếu tồn tại bộ decoder trong interconnect (Trường hợp 1 master access nhiều hơn 2 slave). thì đòi hỏi kênh AW phải đến input của bộ decoder trước vì bộ decoder cần biết tín hiệu address để write đến đúng slave mong muốn.


Câu 2: Trong 1 chu trình write transaction, Khi nào thì BVALID được assert ? 

Nếu WLAST&WVALID&WREADY = 1, thì slave có thể assert BVALID bất chắp AWVALID và AWREADY đã assert hay chưa (Điều này không violate AXI protocol rule).



Câu 3: Một master gửi các thông tin burst size và burst length thông qua các tín hiệu ARSIZE, AWSIZE, ARLEN và AWLEN. Từ các thông tin đó chúng ta có thể tính được số beat trong 1 burst và biết được beat cuối. Tuy nhiên tại sao master và slave lại có thêm tín hiệu WLATS và RLAST để xác định beat cuối trong 1 burst được transfer ? 

Câu trả lời là giúp cho design trở nên đơn giản hơn.

Việc tính toán là hoàn toàn có thể tuy nhiên sẽ làm cho quá trình design cả master và slave trở nên phức tạp hơn và dễ gây bug.



Câu 4: Sự khác biệt giữa AXI4 và AXI3 ?

AXI4 không còn tín hiệu WID. Điều này có nghĩa là kênh W channel sẽ không hỗ trợ out-of-order và write data interleaving. Dữ liệu gửi ra từ kênh W sẽ có cùng thứ tự với dữ liệu gửi ra từ kênh AW (in-order).

Ví dụ:

AWADDR: ADDR_0 -> ADDR1 -> ADDR2

WDATA: DATA_0 -> DATA_1 -> DATA_2

Ngoài ra, Với AXI4, Tín hiệu ARLEN/AWLEN được mở rộng từ 4 bit width thành 8 bit width. Nghĩa là nó có thể hỗ trợ tối đa 256 beat transfer trong 1 burst. Điều này là cần thiết vì công nghệ ngày càng phát triển đòi hỏi tốc độ gửi nhận dữ liệu nhanh hơn. Việc tăng giới hạn số beat trong 1 burst giúp tăng performance của hệ thống vì giảm số transaction kênh AW/AR đi và tăng dữ liệu gửi qua kênh R/W.

Đồng thời tín hiệu AWLOCK/ARLOCK giảm từ 2 bit width xuống còn 1 bit width. 

AXI3
 AXI4

Mình nói 1 chút về tín hiệu này. Giả sử có 1 master A. Trường hợp ARLOCK = 10. Lúc này tín hiệu này sẽ control interconnect để chỉ cho master A đi qua. Các master khác phải đợi cho đến khi ARLOCK của master A = 00 thì mới có thể access. Ta có ARLOCK = 10 , Vậy kênh W có thể access không ? Câu trả lời là có. Nó chỉ block các master khác chứ không block các kênh cùng 1 master.



Câu 5: Tại sao không loại bỏ RID hoặc BID (tương tự như loại bỏ WID trong AXI4) ?

Đó là các channel từ slave gửi về. Nếu chúng ta bỏ nó vô tình lúc này kênh R và B cũng sẽ không support out-of-order. Mình lấy ví dụ:

Gửi 2 request đến 2 slave khác nhau A và B.

Đầu tiên ta phát tín hiệu AR đến slave A sau đó đến slave B. Lúc này nếu không dùng ID thì ta phải đợi slave A response về rồi mới nhận slave B. trường hợp slave A response nhanh thì sẽ không sao, ngược lại nếu slave B response nhanh hơp thì lúc này slave A phải đợi B response về mới được response. Có hai ảnh hưởng:

  • Ảnh hưởng performance của hệ thống.
  • Phải tạo thêm các constraint giữa các slave. Design sẽ trở nên phức tạp hơn.

Câu 6: Phân biệt out-of-order và write data interleaving ?

Out-of-order:  hỗ trợ cho cả kênh R và kênh W.

Write data interleaving: chỉ hỗ trợ cho W channel.


Giả sử ta có 3 transaction, mỗi transaction có 2 beat. Địa chỉ của transaction A được gửi đầu tiên tới B rồi cuối cùng là C.

A (A0, A1)

B (B0, B1)

C (C0, C1)


Out-of-order:

A0, A1, C0, C1, B0, B1


In-oder: 
A0, A1, B0, B1, C0, C1


Write data interleaving: A0, B0, B1, A1, C1, C0.


Lưu ý với out-of-order thì transaction đầu tiên phải ứng với address đầu tiên. Tức là WDATA đầu tiên phải tương ứng với ADDRESS đầu tiên phát ra từ master.


Trong AXI4 nếu có nhiều hơn 2 masters cùng access đến 1 slave. Khối nào sẽ control việc merge các data từ 2 master để đảm bảo không bị interleaving.

Interconect sẽ được thiết kế để đảm bảo điều này. Nếu 2 master có cùng ID gửi xuống slave. Interconnect sẽ giải quyết vấn đề này bằng cách chèn thêm một số bit ID ở đầu các tín hiệu ID. Nghĩa là các tín hiệu ID được mở rộng thêm bit width.

Ví dụ: mình có 4 master A (ARID = 11), B (ARID = 11), C (ARID = 11), D (ARID = 11) cùng gửi request đến slave E. Khi đó interconnect sẽ cần chèn thêm 2 bit đầu để phân biệt 4 master đó như sau:

A (ARID = 0011), B (ARID = 0111), C (ARID = 1011), D (ARID = 1111)

Write data interleave xảy ra khi hai AXI master tạo ra sequence ghi vào cùng một slave, nhưng dữ liệu ghi không đến mỗi chu kỳ xung clock. Trong trường hợp này, thay vì đợi một sequence hoàn thành trước khi chuỗi khác bắt đầu, chuẩn AXI cho phép gửi xen kẽ các chuỗi dữ liệu lại với nhau để tránh lãng phí các chu kỳ xung clock trong hệ thống bus.


Câu 7: Khi master access đến 1 slave có thể vừa có in-oder vừa có out-of-order được gửi xen kẽ nhau không?

Nêu một master access đến 1 slave duy nhất. Lúc này ta có thể thấy nếu các burst có ID trùng nhau thì chúng sẽ được transfer in-order. Nếu các burst có ID khác nhau chúng được transfer out-of-order với các burst có ID khác.
Ví dụ:
Có 4 gói: A (ARID = 1), B (ARID = 3), C (ARID = 2), D (ARID = 2).
Khi đó:
 A, B, C có thể được gửi out-of-order với nhau.
A, B, D có thể được gửi out-of-order với nhau.
C, D phải được gửi in-order.

Trường hợp 1 master access đến nhiều slave. Ví dụ mình có master A gửi 1 burst đến slave B có ARID = 2. Sau đó master này gửi tiếp 1 burst đến slave C có ARID = 2 trong khi chưa nhận được response từ slave B . điều này là violate vì khi data trả về master sẽ không phân biệt được đâu là data response từ B và đâu là từ C (trường hợp out-of-order).
Câu 8: Sự khác biệt giữa RRESP và BRESP ?
Mình giả sử có 1 write transaction và 1 read transaction. Mỗi transaction có 4 beat.

Với kênh read, mỗi beat sẽ được thông báo bởi 1 giá trị  RRESP. Error xảy ra cho từng beat khác nhau.

Ví dụ ta có

Với kênh write, cả 4 beat được control bởi chỉ 1 giá trị BRSEP.






Monday, December 9, 2019

Một số câu lệnh cần thiết khi làm việc với gate net list

Tác giả: TrongTran
Ngày: 09/12/2019


Bài này mình sẽ hướng dẫn các bạn một số câu lệnh tcl để làm việc với gate net list (DC compiler.....).

Tuy nó không đủ nhưng mình tin là với bài viết này và nếu bạn chịu khó đọc thêm thì bạn hoàn toàn có thể hiểu được toàn bộ một môi trường synthesis và làm những công việc với gate cực nhanh (ECO).
Thực tế, một số bạn thích dùng phần mềm trực quan để kiểm tra hoặc debug.
Mình thì dùng cả hai và với một design lớn thì mình thích làm việc với command line hơn. Điều này sẽ giúp bạn rút ngắn được thời gian nhiều hơn.

Mình không làm backend nên mình không biết hết tất cả các lệnh. Mình chỉ nêu ra một số lệnh cần thiết và cơ bản nhất.

Trong bài này mình quy định màu đỏ là cú pháp câu lệnh. Màu xanh là option của câu lệnh và màu đen là phần người dùng điền vào (Có thể là tên biến, key word tìm kiếm ....).


Lệnh đầu tiên mình muốn nói là:

  • read_verilog design.v
  • current_design /current_block /current_lib
  • close_lib design.v
3 lệnh trên có chức năng là:
  • Load file Verilog design.v
  • Kiểm tra design hiện tại đang được load.
  • Đóng file Verilog design.v



get_cell tên_cell

get_cells -[option] tên_cell


Hai câu lệnh trên là nhầm lấy các cell trong một design dựa vào key word trong đã biết.

Ví dụ: bạn muốn lấy 1 cell có chứa key word “AND” bạn dùng lệnh:

get_cells -hierarchical *AND*

Điểm khác biệt giữa get_cells và get_cell là get_cell không dùng được với option còn get_cells thì có.

Một điểm lưu ý nữa là khi bạn có link đầy đủ của 1 cell thì bạn có thể dùng lệnh

get_cells top/AND (Nhớ là không dùng option –hierarchical nhé).

Còn khi bạn chưa biết link instance đầy đủ hoặc cần lấy tất cả các cell chứa key word nào đó bạn dùng lệnh:

get_cells –hierarchical *AND*




get_net tên_net

get_nets –[option] tên_net

Hai câu lệnh này nhầm lấy net name trong design dựa vào key word đã biết. Cách dùng tương tự hai câu lệnh get_cell bên trên.

Để tạo ra một bộ collection của các phần tử (cell, net, port, ….) bạn dùng cặp lệnh:

set NET_COL {}

set NET_COL [add_to_collection $NET_COL [get_nets -hierarchical "AND"]]

Dòng đầu là để khai báo bộ collection tên NET_COL.

Dòng thứ hai là để tìm tất cả các net chứa key word “AND” và lưu vào collection NET_COL.

set NET_TARGET {}

set NET_REMOVE{}

set NET_TARGET [add_to_collection $NET_TARGET [get_nets -hierarchical "AND"]]

set NET_REMOVE [add_to_collection $NET_REMOVE [get_nets -hierarchical "2"]]

set NET_TARGET [remove_from_collection ${NET_TARGET} ${NET_REMOVE}]

Giả sử bạn tìm được các net chứa key word “AND”. Bây giờ bạn cần loại bỏ các net chứa key word số “2” trong bộ collection trên. Tập lệnh bên trên sẽ giúp bạn.

if {[sizeof_collection $NET_TARGET] != 0} {

}

Dòng code trên đang tiến hành kiểm tra xem liệu bộ collection NET_TARGET có chứa phần tử nào không (size # 0), nếu có thì tiến hành các lệnh bên trong dấu ngoặc {}.

foreach_in_collection port_gnd_0 $NET_TARGET {

}

Dòng code trên nhầm lấy từng phần tử trong bộ sưu tập NET_TARGET ra để tiếp tục xử lí bên trong cặp dấu {}. Cái này giống câu lệnh foreach trong cshell nhé.


Lúc bạn lưu net name vào bộ sưu tập NET_COL, các giá trị sẽ lưu dạng 1 phần tử trong design chứ không phải dạng chuỗi.

Nếu bạn muốn chuyển phần tử đó sang dạng chuỗi nhầm dễ xử lí hãy dùng câu lệnh:

set name_2 [get_object_name $port_gnd_0]

Trước khi thực hiện câu lệnh này, bạn phải thực hiện câu lệnh bên trên nhầm chuyển phần tử sang chuỗi nhé. Giả sử trong bộ collection đó, bạn chỉ muốn thao tác với một vài phần tử có chứa key word cụ thể. Bạn nên dùng lệnh bên dưới, Câu lệnh này được dùng thường xuyên luôn nhé, hãy ghi nhớ thật kĩ:

if {[regexp "sync" $name_2]} {

}

Hoặc

if {[regexp {A|B} $name_2]} {

}

Hoặc

if {[regexp {A&B} $name_2]} {

}

Câu lệnh số 2 là nếu chứa key word A hoặc B.

Câu lệnh số 3 là nếu chứa key word A và B.


Bạn đang có 1 collection của các port. Bây giờ bạn muốn chỉ xử lí chỉ các port output. Câu lệnh bên dưới sẽ giúp bạn. Tương tự cho các port input nhé (Thay “out bằng “in”).

if {[get_attribute ${port} direction] == "out"} {

}

Để kiểm tra xem port /net cụ thể có bao nhiêu phân nhánh mình có câu lệnh bên dưới:

set fanout_name [sizeof_collection [all_fanout -from [get_ports “AND”]]]

Câu lệnh để kiểm tra xem có tồn tại thư mục với tên nào đó không. Ta có câu lệnh sau:

if { [file exists $FOLDER] && [file isdirectory $FOLDER] } {

}

In ra một chuỗi, Bạn có lệnh sau:

puts “Hello world”

Để chạy 1 script viết bằng ngôn ngữ khác trong file tcl, Bạn có câu lệnh sau:

exec ./run.pl

Đễ chạy 1 câu lệnh cshell trong file tcl bạn chạy lệnh như bên dưới:

sh mkdir folder

Khi bạn có 1 link của instance name và bạn muốn biết module name của instance này là gì trong design hãy dùng câu lệnh sau:

get_attribute top/sub_0/sub_1 ref_name

Câu lệnh get_attribute rất mạnh nhé. Hãy vào chế độ command line của các tool và chạy lệnh:

man get_attribute

Để biết được hướng dẫn của chúng.

Nếu bạn còn có câu lệnh nào chưa biết hãy gửi mail hoặc comment góp ý với mình nhé.

Thursday, December 5, 2019

Thảo luận 1 lỗi mismatch bit width trong thiết kế verilog rất khó được phát hiện

Tác giả: TrongTran
Ngày: 05/12/2019


Trước đây mình có trình bày về 1 issue liên quan đến lỗi 2 output được connect vào 1 port.
Trong bài này, Đây là 1 bug mới mà một anh trong công ty mình tạo ra. Với hầu hết các lỗi liên quan đến mismatch bit width thì các tool sẽ phát hiện được. Nhưng lỗi này, Mình đã tiến hành kiểm tra bằng nhiều loại tool và kết quả là không phát hiện được.

Mình xét ví dụ nhỏ:





Trong ví dụ trên mình muốn các bạn đặt sự tập trung vào dòng nằm trong hình chữ nhật đỏ bên trên.
Function của module này cơ bản chỉ là:
  • 2 input XOR với nhau sau đó đi qua mạch 2 flip flop. 


Tuy nhiên, ở đây mình cố tình khai báo biến reg async_ff có 1 bit width. Điều này sẽ dẫn đến mismatch bit width vì biến result là 1 signal có 2 bit data. Như vậy mismatch bit width sẽ diễn ra tại dòng 31 và 32 trong hình trên.

Điều gì sẽ xảy ra?

Mình đã chạy hàng loạt các tool để kiểm chứng kết quả là:
  • VCS không warning cũng không error.
  • Cadence incisive không warning cũng không error.
  • Cadence xcelium không warining cũng không error.
  • Synthesis  không warning không error và formality vẫn pass.

Mọi thứ quá hoàn hảo để không phát hiện được issue này.
Bây giờ hãy thử kiểm tra function nhé:

Mình có 1 test bench như bên dưới:

module tb();
  
  reg [1:0] in_0;
  reg [1:0] in_1;
  wire [1:0] out;
  reg clk;
  
  
  initial begin
     clk = 1;
     forever #10 clk = ~clk;
  end
  
  top top_0 (.clk(clk), .in_0(in_0), .in_1(in_1), .out(out));
  
  initial begin
    #20;
    in_0 = 2'b00;
    in_1 = 2'b11;
    #20;
    in_0 = 2'b00;
    in_1 = 2'b00;
    #20;
    in_0 = 2'b11;
    in_1 = 2'b11;
    #20;
    in_0 = 2'b10;
    in_1 = 2'b11;
    #20;
    in_0 = 2'b10;
    in_1 = 2'b01;
    #20;
    $finish();
  end
    initial begin
         $dumpfile("dump.vcd");
          $dumpvars(0, tb);
     end  
endmodule

Và đây là waveform:


Vì kết quả bị delay 2 chu kì nên vòng xanh thứ nhất là input
in_0 = 2'b00;
in_1 = 2'b11;

Nếu in_0 ^ in_1 = 2'b11;
Thực tế kết quả là 2'b01.
Biến mismatch đã được fix giá trị 0.
Các bạn có thấy lạ không. Vì rõ ràng là biến result tại dòng 13 đã được gán 
result = in_0 ^ in_1;

nên giá trị phải là 1 chứ nhỉ ? và giá trị out[1] không bị delay 2 chu kì như out[0] vì out[1] không qua 2 flip flop do mismatch bit width ?

Không phải nhé, Thực ra giá trị out[1] = 0 là chính xác đấy. Lí do chỉ có out[0] được gán tại dòng 32, còn out[1] không được gán giá trị nên sẽm ang giá trị 0. Biến result khác out nhé.

Như vậy check function sẽ phát hiện được lỗi này.
Thế nhưng bạn có chắc bạn check đủ case cho nó. Mình vừa đối mặt issue này bởi signal sai là signal STROBE trong kênh W channel.
Thường thì chúng ta không verify đủ case của tín hiệu này. Ví dụ: 

WDATA có 64 bit bạn phải check đủ các case cho tín hiệu 0f, ff.....
Hãy thận trọng.

Gate netlist cũng sẽ fix 0 cho tín hiệu gán thiếu như bên dưới:

module top (clk, in_0, in_1, out) ;
    input  clk ;
    input  [1:0] in_0 ;
    input  [1:0] in_1 ;
    output [1:0] out ;

    wire net_2 ;
    wire net_1 ;
    wire result ;
    wire FLT_1 ;
    wire FLT_2 ;

    sub_top_0 sub_0 (.clk(clk), .result({FLT, result}), .out({FLT, net_1}));


    XOR2 xor_0 (.A1(in_0[0]), .A2(in_1[0]), .Z(result));
    BUFF buf_1 (.I(1'b0), .Z(net_2));
    BUFF buf_2 (.I(net_2), .Z(out[1]));
    BUFF buf_3 (.I(net_1), .Z(out[0]));

endmodule


module sub_top_0 (clk, result, out);
    input  clk;
    input  [1:0] result;
    output [1:0] out;

    wire [0:0] async_ff;

    DFF dff_1 (.D(async_ff[0]), .CP(clk), .Q(out[0]));
    DFF dff_2 (.D(result[0]), .CP(clk), .Q(async_ff[0]));
endmodule


Thế thì spyglass có phát hiện lỗi này. Câu trả lời là có mà là WARNING ???????
Bạn sẽ nhận được mã sau:

RP_UnmatchWidth    4.4.1(3)       Warning     top.v    31      10    Bit width of LHS does not match with RHS on the assignment
RP_UnmatchWidth    4.4.1(3)       Warning     top.v    32      10    Bit width of LHS does not match with RHS on the assignment

Nhưng với một design lớn. Có hàng ngàn mã lỗi như vậy. Vì sao? Một số case như sau:

wire [3:0] b;
assign b = 0;

Vâng, Cái này nó cũng warning y như cái trên đấy. Còn một vài case nữa nhưng mình ko tiện nêu ra. Do đó không phải dễ để tìm ra lỗi này. Hãy thận trọng confirm tất cả error dạng này nhé.
Qua 2 issue mình nêu bạn sẽ thấy sức mạnh của tool spyglass từ synopsys mạnh như thế nào. Hãy tận dụng nó một cách có hiệu quả, bạn sẽ tránh được các issue không đáng có.

Mọi góp ý về issue này hãy call cho mình nhé: 0339339692.

Code ví dụ cho bạn nào muốn trial lại:

module top (clk, in_0, in_1, out);
    input [1:0] in_0;
    input [1:0] in_1;
    output [1:0] out;
    input clk;

    wire [1:0] out;
    wire [1:0] result;

    sub sub_0 (.clk(clk), .result(result), .out(out));
    assign result = in_1 ^ in_0;
endmodule

module sub (clk, result, out);

   input clk;
   input [1:0] result;
   output[1:0] out;
   reg [0:0] async_ff;
   reg [1:0] out;


   always @(posedge clk) begin
         async_ff <= result;
         out <= async_ff;
   end
endmodule







Cách tính BW và latency trong 1 hệ thống SoC sử dụng chuẩn giao tiếp AXI protocol

Tác giả:  TrongTran Ngày:  31/12/2019 Nếu bạn nào đang làm về verification cho system performance (ST) thì bài này sẽ bổ ích cho bạn. Ngày ...