• Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

  • Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

  • Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

Thứ Bảy, 22 tháng 9, 2018

[DFT] Các phương pháp thiết kế DFT

Qua bài viết mô tả tổng quan về DFT, chúng ta có thể hiểu cơ bản về kỹ thuật DFT. Kỹ thuật DFT có nhiều phương pháp thực hiện khác nhau gồm phương pháp Ad-hoc, phương pháp scan, phương pháp BIST. Bài này sẽ mô tả cơ bản về các kỹ thuật này.

1) Điều khiển, giám sát và dự đoán
Khả năng điều khiển (controllability), giám sát (observability) và dự đoán (predictability) là ba yếu tố quan trọng nhất đánh giá khả năng test (testability) của một mạch.
Khả năng điều khiển là khả năng thiết lập (lái) một tín hiệu đến một giá trị mong muốn thông qua các đầu vào (input) của mạch. Giá trị này có thể là mức 0 hoặc mức 1. Một tín hiệu có thể được điều khiển là một tín hiệu có thể được lái đến mức "0" và mức "1" bằng một tập test pattern nhất định. Một tín hiệu không thể điều khiển là tín hiệu không thể được lái đến mức "0" hoặc mức "1" hoặc cả hai thông qua tập test pattern hiện có. Một tín hiệu không thể điều khiển thì tín hiệu này không thể test được.
Khả năng giám sát là khả năng xác định giá trị của một tín hiệu trong mạch thông qua việc giám sát (đọc) đầu ra (output) của mạch. Một tín hiệu có thể được điều khiển đến giá trị logic mong muốn nhưng không thể kiểm tra được kết quả này thì cũng không thể test được.
Khả năng dự đoán là khả năng ngõ ra đạt được các giá trị có thể nhận biết đáp ứng theo giá trị ngõ vào đã biết. Khả năng này bị ảnh hưởng bởi trạng thái khởi tạo của mạch, chạy đua, hazard, và các dao động tự do. Khi giá trị ngõ ra không thể xác định (dự đoán) trước là "0" hay "1" thì không thể test được.
Các phương pháp thực hiện DFT đều có mục tiêu chính là cải thiện khả năng test thông qua việc tăng khả năng điều khiển, giám sát và dự đoán của mạch. Các phương pháp DFT hiện nay được chia thành 2 nhóm là nhóm phương pháp Ad-hoc và nhóm phương pháp có cấu trúc (structured).
2) Phương pháp Ad-hoc
Ad-hoc có ý nghĩa là "for this", đây là một thuật ngữ chỉ một giải pháp hoặc một phương pháp để giải quyết một vấn đề cụ thể hoặc dành cho một mục đích cụ thể chứ thể khái quát để dành cho nhiều mục đích khác nhau. Phương pháp Ad-hoc là phương pháp chỉ nhắm đến các phần không thể test (untestability) được hoặc các phần rất khó để test trong một thiết kế.
Phương pháp này sẽ thêm DFT logic, gọi là test point, để tăng khả năng điều khiển, giám sát và dự đoán cho các phần mạch khó hoặc không thể test được. Có hai loại test point là:
  • Controllability test point, gọi tắt là control point (CP), dùng để cải thiện khả năng điều khiển của điểm (vị trí) cần test
  • Observability test point, gọi tắt là observation point (OP), dùng để cải thiện khả năng giám sát của điểm (vị trí) cần test.
Phương pháp Ad-hoc cũng theo nguyên tắc chung của kỹ thuật DFT là giải quyết vấn đề "làm sao để điều khiển và giám sát trực tiếp điểm muốn test?". Một cấu trúc đơn giản của test point là dùng MUX.
Hình 1: Cấu trúc test point sử dụng MUX
Hình 2 là một ví dụ về chèn test point cho điểm na.
Hình 2: (a) mạch gốc (b) mạch được chèn thêm control point và observation point cho điểm na
Control point dùng MUX giúp lái na đến giá trị mong muốn 0 hoặc 1 dễ dàng. Hình 3 minh họa một cách chèn control point chỉ cho phép lái điểm na đến giá trị 0 (hình a) và chỉ cho phép lái điểm na đến giá trị 1 (hình b). Control point loại này còn gọi là "force test point".
Hình 3: (a) control point chỉ cho phép lái đến giá trị 0 (b) control point chỉ cho phép lái đến giá trị 1
Trong phương pháp Ad-hoc, khi số lượng các control point tăng lên thì số chân test input sẽ tăng lên, mỗi control point có một test input riêng, làm số chân ngõ vào của chip tăng lên. Khi số lượng observation point tăng lên thì số tín hiệu internal point tăng lên nên số lượng chân ngõ ra chip cũng không thể đáp ứng được nếu mỗi ngõ ra chỉ giám sát một internal point.
Để giảm số lượng chân ngõ vào của chip khi số lượng control point tăng, một DEMUX sẽ được sử dụng, để phân phối giá trị đến các control point từ một ngõ vào duy nhất như hình 4. Trong hình 4a, giả sử số lượng control point là n thì số lượng tín hiệu điều khiển DEMUX là x với 2^x >= n. Giá trị của mỗi đầu vào control point cần được lưu lại để điều khiển nên tại mỗi ngõ ra DEMUX sẽ có một FF như hình 4b. DEMUX cần x tín hiệu điều khiển sel_0, sel_1, ..., sel_x. Chúng không thể lấy từ các chân ngõ vào của chip vì nó sẽ làm chip tăng thêm chân không mong muốn. Giải pháp là có thể sử dụng một bộ đếm để mỗi chu kỳ clock bộ đếm tăng 1 giá trị và lựa chọn 1 ngõ ra DEMUX nối với test_in như hình 4c. Bên cạnh đó, chân test_in không cần là một chân riêng, nó có thể được tích hợp trong một chân chức năng của chip như hình 4d.
Hình 4: (a) DEMUX để điều khiển giá trị các control point (b) Dùng FF để lưu lại giá trị điều khiển (c) Thêm bộ đếm điều khiển DEMUX (d) Chân test_in có thể tích hợp với một chân chức năng khác
Đối với các observation point, để giảm số chân ngõ ra, chúng ta dùng một MUX để lựa chọn điểm giám sát như minh họa hình 5.

Hình 5: (a) Dùng MUX để lựa chọn điểm giám sát (b) Dùng bộ đếm điều khiển MUX và chân test_out có thể tích hợp với chân chức năng khác
Phương pháp Ad-hoc có lợi thế là giúp nhanh chóng giải quyết một vấn đề cụ thể nhưng việc thiết kế và chèn các test point theo phương pháp này phụ thuộc vào kinh nghiệm của người thực hiện. Vì vậy, việc phân tích và thiết kế DFT có thể phải lặp lại nhiều lần để đạt được mục tiêu coverage mong muốn. Bên cạnh đó, việc kiểm tra và đánh giá thiết kế DFT cũng mất thời gian hơn.
3) Phương pháp scan
Phương pháp scan thuộc nhóm phương pháp có cấu trúc. Phương pháp này chia thành các nhóm phổ biến như sau:
  • Scan nối tiếp (serial scan)
    • Scan toàn phần (full-scan)
    • Scan một phần (partial-scan)
  • Scan không nối tiếp (nonserial scan)
Khi trình bày về khái niệm DFT trong bài mô tả sơ bản về DFT, tác giả đã dùng phương pháp scan để minh họa việc thực hiện DFT như thế nào. Để thực hiện được phương pháp này, mỗi FF sẽ có thêm một MUX gắn ở ngõ vào D để lựa chọn giữa giá trị đầu vào giữa chế độ test (DFT) và chế độ xử lý thông thường.
Trong thực tế, người thiết kế sẽ không thêm MUX này bằng tay. Các phần mềm chuyên dụng như DFT compiler (Synopsys) sẽ làm việc này. Mỗi thư viện công nghệ dùng để tổng hợp đều hỗ trợ hai loại FF là loại có chức năng thông thường (non-scan FF) và loại hỗ trợ chức năng scan (scan FF). Trong đó:
  • Non-scan FF là FF thông thường, không hỗ trợ chức năng scan, hình 6.
  • Scan FF là FF có tích hợp sẵn MUX bên trong cho phép lựa chọn giữa chức năng thông thường và chế độ DFT, hình 7.
Hình 6: Sơ đồ mạch nguyên lý của Non-scan FF
Hình 7: Sơ đồ mạch nguyên lý của Scan FF sử dụng MUX
Khi tổng hợp RTL code để tạo ra GATE netlist , chúng ta sẽ làm những bước sau:
  1. Chuyển RTL code thành GATE netlist dùng non-scan FF bằng phần mềm tổng hợp như Design Compiler (Synopsys). Các dòng RTL code viết bằng Verilog hoặc VHDL sẽ được chuyển thành một netlist. Netlist gọi các cell của thư viện công nghệ và kết nối các cell này để tạo thành những mạch có chức năng tương đương với RTL code.
  2. Chuyển GATE netlist dùng non-scan FF (pre-DFT) thành GATE netlist dùng scan FF (post-DFT) bằng phần mềm tổng hợp như DFT compiler (Synopsys). Bước này chuyển các non-scan FF trong netlist thành các scan FF.
Scan toàn phần (full-scan) là phương pháp thay toàn bộ các non-scan FF trong thiết kế thành scan FF, hình 8.
Hình 8: (a) Mạch pre-DFT sử dụng non-scan FF (b) minh họa về scan toàn phần, toàn bộ non-scan FF được thay bằng scan FF
Scan một phần (partial-scan) là phương pháp chỉ chọn một phần các non-scan FF để chuyển thành scan FF, hình 9.
Hình 9: Minh họa về scan một phần (partial-scan)
Trong phương pháp scan nối tiếp, giá trị của một FF không thể được điều khiển và giám sát độc lập (trực tiếp). Mỗi FF là một phần của chuỗi scan, khi cần điều khiển và giám sát một FF thì phải tác động đến toàn bộ chuỗi scan. Phương pháp scan ngẫu nhiên (Random-access scan - RAS) sẽ tránh được điều này. RAS là một phương pháp non-serial scan. Trong phương pháp này, mỗi FF được xem như một ô nhớ trong một mảng bộ nhớ, tương tự như RAM. Mỗi FF sẽ có một giá trị địa chỉ cho phép "ghi" (điều khiển) và "đọc" (giám sát) trực tiếp FF.
Hình 10: Random-access scan, một loại non-serial scan
Phương pháp RAS có bất lợi lớn và phần mạch giải mã địa chỉ (address decoder) sẽ lớn đáng kể khi số lượng FF tăng lên.
4) Phương pháp BIST
BIST là viết tắt của Built-In Self-Test, đây là một kỹ thuật cho phép một chip tự tạo ra các test pattern và tự kiểm tra các mạch bên trong nó rồi báo kết quả PASS/FAIL. Với kỹ thuật này, để test một thành phần bên trong chip, các test pattern không cần phải cung cấp từ bên ngoài, việc phân tích kết quả cũng không cần phải thực hiện bên ngoài chip như kỹ thuật Ad-hoc hay scan nên BIST có một ưu điểm lớn là giảm thời gian test và giảm chi phí test chip.
Cấu trúc BIST gồm các phần cơ bản sau đây:
  • Bộ tạo test pattern (Test pattern generator - TPG)
  • Bộ phân tích đáp ứng ngõ ra (Output Response Analyzer - ORA)
  • Bộ điều khiển BIST (Test controller)
Hình 11: Minh họa kỹ thuật BIST
Kỹ thuật BIST có thể được áp dụng để test logic của thiết kế (Logic BIST - LBIST) và bộ nhớ (Memory BIST - MBIST).

Thứ Bảy, 8 tháng 9, 2018

[DFT] Mô tả cơ bản về DFT - Design For Test

Bài viết này trình bày tổng quan về khái niệm DFT (Design For Test), tại sao cần phải có DFT? và kỹ thuật DFT được áp dụng như thế nào?

1) DFT là gì? Tại sao cần phải có DFT?
DFT là một kỹ thuật giúp cho một thiết kế có thể được kiểm tra (test) dễ dàng và đầy đủ hơn sau khi sản xuất thành chip mà không cần quan tâm đến chức năng của mạch (thiết kế). Một quy trình sản xuất không thể đảm bảo toàn bộ chip được sản xuất ra đều đạt chất lượng và không có lỗi. Lỗi ở đây là lỗi vật lý (physical fault) sinh ra so quá trình sản xuất, không phải lỗi chức năng hay lỗi logic (logical fault) do thiết kế sai. Lỗi chức năng do thiết kế sai phải được phát hiện khi mô phỏng và kiểm tra trước khi sản xuất.
Một số lỗi vật lý có thể gặp như nối đất GND (stuck-at-0, s-a-0), nối nguồn  VCC (stuck-at-1, s-a-1), ngắn mạch (short), hở mạch (open). Một lỗi vật lý sinh ra sẽ làm cho hoạt động của chip bị sai hoặc không thể hoạt động.
Hình 1: Các lỗi vật lý có thể sinh ra trong quá trình sản xuất chip
Để dễ hình dung, các bạn hãy liên tưởng đến việc kiểm tra các bo mạch in (PCB), một bo mạch in sau khi sản xuất phải được kiểm tra xem các đường mạch có bị nối GND, VCC, ngắn mạch hay hở mạch (bị đứt) hay không. Chip cũng cần được kiểm tra các lỗi như vậy. Một chip gồm hai phần logic là user logic và DFT logic. Trong đó, user (function) logic là thành phần xử lý các chức năng dành cho người dùng chip, DFT logic dùng để test chip.
Hình 2: Một vi mạch gồm User logic and DFT logic
Tóm lại, kỹ thuật DFT là kỹ thuật giúp kiểm tra chip dễ dàng và đầy đủ hơn bằng cách thêm các logic dùng cho việc test vào trong chip. Nếu không có DFT, một chip vẫn có thể được kiểm tra thông qua đo đạc và chạy các test chức năng (fucntion test) trên chip nhưng thời gian test rất lâu và không đảm bảo toàn bộ chip được test đầy đủ (coverage thấp). Ví dụ, một chip không có DFT, nếu chạy các test chức năng có thể mất 30 giây (hoặc nhiều hơn) cho một chip thì tổng thời gian test cho một lô sản phẩm 100.000 chip là khoảng 35 ngày, cho 1 triệu chip là 347 ngày. Nhưng với kỹ thuật DFT, tổng thời gian test có thể giảm hơn 10 lần. Tuy nhiên, việc áp dụng kỹ thuật DFT sẽ làm kích thước chip lớn hơn do phải thêm các logic phục vụ việc test.
2) Mạch DFT được thực hiện như thế nào?
Phần này sẽ trình bày một số ví dụ cơ bản để hiểu kỹ thuật DFT được thực hiện như thế nào? áp dụng ở bước nào trong quy trình thiết kế vi mạch số? và các khái niệm cơ bản liên quan đến kỹ thuật DFT. Để minh họa cho phần này, chúng ta xét ví dụ hình 3. Mạch này có chức năng tìm mức logic chiếm ưu thế từ các ngõ vào in1, in2 và in3:
  • Nếu 2 hoặc 3 ngõ vào có mức logic "0" thì ngõ ra out_z = 0
  • Nếu 2 hoặc 3 ngõ vào có mức logic "1" thì ngõ ra out_z = 1
Verilog code của mạch này như sau:
assign a12 = ~(in1 & in2);
assign a13 = ~(in1 & in3);
assign a23 = ~(in2 & in3);
assign out_z = ~(a12 & a13 & a23);
Hình 3: (a) Bảng sự thật (b) Sơ đồ nguyên lý
Trước khi gửi bản thiết kế đi sản xuất, các lỗi chức năng (function/logic fault) của mạch hình 3 sẽ được tìm thấy thông qua kiểm tra chức năng (function verification) bằng cách cung cấp các giá trị đầu vào cho in1, in2 và in3 và giám sát giá trị ngõ ra out_z thông qua một testbench nếu sử dụng phương pháp mô phỏng (simulation) hoặc bằng một mô hình tương đương nếu sử dụng phương pháp kiểm tra formal. Nếu out_z luôn đúng với tất cả các tập giá trị ngõ vào in1, in2 và in3 như bảng sự thật thì ta nói chức năng của mạch này được coverage 100% (function coverage).
Sau khi sản xuất thành chip hoàn chỉnh, để có thể phát hiện được các lỗi sinh ra trong quá trình sản xuất chúng ta có thể:
  • Chạy thử nghiệm từng chức năng cụ thể của chip. Cách này tốn nhiều thời gian test như đã trình bày ở phần trên.
  • Sử dụng kỹ thuật DFT. Cách này giảm thời gian test nhưng có thể phải thêm nhiều logic để hỗ trợ việc này.
Trước khi chip được sản xuất, người thiết kế phải phân tích "chiến lược" (kế hoạch) test chip để xác định xem thiết kế hiện tại có khả năng test được các lỗi vật lý ở mức chip hay không? Về cơ bản, hai hoạt động chính của việc phân tích và thiết kế DFT là:
  • Mô hình hóa các lỗi vật lý (fault modelling) để dự đoán các lỗi có thể xuất hiện và đưa ra giải pháp để phát hiện các lỗi này.
  • Thiết kế logic hỗ trợ việc phát hiện các lỗi vật lý nếu cần. Chú ý, việc thêm DFT logic là để giúp việc test ở mức chip dễ dàng hơn, tuy nhiên trong một số trường hợp, DFT logic không cần phải thêm mà vẫn có thể test được.
Giả sử, xét đường kết nối nội bộ a12, trong hoạt động thông thường, đường a12 sẽ đáp ứng theo các giá trị của hai ngõ vào in1 và in2. Nhưng nếu có lỗi vật lý xảy ra như bị nối GND hay nối VCC, giá trị đường này có thể bị giữ cố định ở mức logic "0" (stuck-at-0) hoặc "1" (stuck-at-1). Stuck-at-1 và stuck-at-0 chính là các mô hình lỗi (fault model). Làm thế nào để kiểm tra hai lỗi này trên đường a12?
  • Để kiểm tra stuck-at-1: Lái a12 được lái đến mức logic 0 và kiểm tra a12. Nếu a12 đúng bằng "0" thì kết luận a12 không bị lỗi stuck-at-1.
  • Để kiểm tra stuck-at-0: Lái a12 được lái đến mức logic 1 và kiểm tra a12. Nếu a12 đúng bằng "1" thì kết luận a12 không bị lỗi stuck-at-0.
Tiếp theo, giải pháp để phát hiện các lỗi đã được mô hình hóa cho đường a12 là gì? Làm sao để lái a12 đến giá trị mong muốn? Làm sao để giám sát giá trị trên đường a12 là đúng hay sai? Ở mức chip, việc điều khiển và giám sát các tín hiệu (đường) nội bộ, như a12, a13 và a23, chỉ có thể thông qua các chân (port, pin) chip, ví dụ như là in1, in2, in3 và out_z trong trường hợp này.
Một đường kết nối bên trong chip chỉ được kiểm tra khi nó có thể được điều khiển đến giá trị mong muốn (controllable) và có thể được giám sát (observable). Trong ví dụ hình 3, a12 có thể được điều khiển đến giá trị mong muốn thông qua in1 và in2. Đường a12 có thể được kiểm tra thông qua ngõ ra out_z. Như vậy, đường a12 có cả hai thuộc tính controllable và observable.
Hình 4: Khả năng test ở mức chip
Để kiểm tra một đường kết nối bên trong chip, một hoặc nhiều tập giá trị ngõ vào được tạo ra để lái đường cần test đến giá trị mong muốn. Các tập giá trị này gọi là các "mẫu kiểm tra" (test-pattern). Để test hai mô hình lỗi stuck-at-1 và stuck-at-0 cho đường a12, chúng ta cần các test-pattern như sau:
  • Stuck-at-1:
    • Test-pattern 1: in1=in2=1 để a12 = 0 và in3=0 để a13=a23=1, ngõ ra out_z sẽ được giám sát và kiểm tra với giá trị mong muốn là out_z=1. Nếu chỉ dùng test-pattern 1, kết quả không đủ để khẳng định "a12 không bị lỗi struck-at-1" vì out_z=1 có thể do a13=0 hoặc a23=0 nếu một trong hai đường này bị stuck-at-0. Vì vậy, chúng ta cần thêm test-pattern để khẳng định a13 và a23 không bị stuck-at-0.
    • Test-pattern 2: in1=in2=in3=0 để a12=a13=a23=1 và giám sát ngõ ra out_z=0. Kết quả của test-pattern này có thể khẳng định a13 và a23 không thể bị stuck-at-0 vì out_z=0 chỉ khi a12=a13=a23=1.
  • Stuck-at-0: Để kiểm tra trường hợp này, chúng ta có thể dùng test-pattern in1=in2=in3=0 và giám sát ngõ ra out_z=0. Chú ý, nếu out_z=0, chúng ta có thể kết luận "a12 không bị lỗi stuck-at-0" còn nếu out_z=1 chúng ta không thể kết luận "a12 bị lỗi stuck-at-0" vì có thể là do a13 hoặc a23 bị lỗi này. Tuy nhiên, việc xác định đường nào bị lỗi không quan trọng trong trường hợp này vì nếu test-pattern này FAIL vì bất cứ nguyên nhân nào thì chip sẽ bị loại bỏ và không được sử dụng.
Trong phân tích trên, lỗi struck-at-1 cần 2 test-pattern để kiểm tra, lỗi stuck-at-0 chỉ cần 1 test-pattern để kiểm tra. Trong đó, test-pattern để phát hiện lỗi stuck-at-0 có thể là trùng với test-pattern 2 dùng để phát hiện lỗi stuck-at-1. Bên cạnh đó, để phát hiện lỗi stuck-at-0, chúng ta có thể sử dụng một trong các test-pattern sau để giám sát out_z=0:
  • in1=in2=in3=0
  • in1=in2=0, in3=1
  • in1=in3=0, in2=1
  • in2=in3=0, in1=1
Với thiết kế trong ví dụ hình 2, giả sử đây là một thiết kế chip hoàn chỉnh, chúng ta không cần thêm DFT logic để test vì bản thân mạch này đã hỗ trợ khả năng test ở mức chip. Trường hợp này, chúng ta chỉ cần tạo ra các test-pattern để sử dụng. Các test-pattern này không cần phải đầy đủ toàn bộ các tổ hợp giá trị ngõ vào của in1, in2 và in3 vì mục tiêu của chúng ta là kiểm tra được các mô hình lỗi để tìm ra các lỗi vật lý chứ không phải kiểm tra đầy đủ chức năng.
Trước khi sản xuất, các test-pattern được sử dụng để đánh giá khả năng phát hiện lỗi thông qua bước mô phỏng lỗi (fault simulation). Fault simulation là mô phỏng một thiết kế trong điều kiện lỗi. Bước mô phỏng này dùng để đánh giá xem có bao nhiêu lỗi có thể được phát hiện trên một số lượng test-pattern cụ thể. Số lượng lỗi có thể phát hiện sẽ được thể hiện bằng thông số fault coverage.
fault coverage (%) = (tổng số lỗi được phát hiện/tổng số lỗi có thể phát hiện)*100
Fault coverage đánh giá khả năng phát hiện lỗi của một tập test-pattern ứng với một mô hình lỗi nhất định, ví dụ như mô hình lỗi stuck-at.
Hình 5: Mô hình mô phỏng lỗi - Fault simulation
Fault simulation được thực hiện bằng cách so sánh kết quả của một thiết kế không lỗi (golden design) và một thiết kế chứa các mô hình lỗi cần test (design with fault model) trên cùng một tập test-pattern. Nếu kết quả hai ngõ ra khác nhau, nghĩa là một lỗi đã được phát hiện. Nếu kết quả hai ngõ ra giống nhau, nghĩa là test-pattern hiện tại không thể phát hiện lỗi đã được giả định.
Ví dụ hình 3 là một mạch tổ hợp đơn thuần, trong trường hợp mạch tuần tự có chứa FF thì sao? chúng ta xét ví dụ về một thiết kế như hình 6, đây là một thanh ghi dịch cho phép ghi giá trị ban đầu khi we=1.
Hình 6: Một thanh ghi dịch cho phép ghi giá trị ban đầu
Làm sao để phát hiện lỗi trên các đường kết nối nội bộ như n0, a0, a1, a2, a3, or0 hay or1? Mạch tuần tự thực chất gồm 2 phần cơ bản là phần mạch tổ hợp và FF. Chúng ta có thể tách riêng các phần mạch tổ hợp ra để xem xét từng phần như hình 7.
  • com0 là phần mạch tổ hợp tại ngõ vào của FF0. com0 chỉ là một dây dẫn.
  • com1 là phần mạch tổ hợp tại ngõ vào của FF1.
  • com2 là phần mạch tổ hợp tại ngõ vào của FF2.

Hình 7: Phân tách phần mạch tổ hợp và FF để xem xét
Ví dụ, xét đường a0 của com1, đường này có thể được điều khiển dễ dàng thông qua các chân ngõ vào và kết quả được giám sát thông qua giá trị chân shift_out[1].
  • Kiểm tra stuck-at-1: we=0, FF0 được gán giá trị 0 thông qua din[0], kiểm tra giá trị trên shift_out[1] phải bằng 0.
  • Kiểm tra stuck-at-0:  we=0, FF0 được gán giá trị 1 thông qua din[0], kiểm tra giá trị trên shift_out[1] phải bằng 1.
Hình 8: Mô phỏng lỗi để xác định stuck-at-0 (trái) và stuck-at-1 (phải)
Đối với ví dụ này, các đường bên trong thiết kế vẫn có thể được lái dễ dàng thông qua các ngõ vào thiết kế và giám sát qua các ngõ ra thiết kế nên không cần thêm các DFT logic trong trường hợp này. Do mạch có FF nên cần chú ý thời điểm cung cấp test-pattern cho thiết kế và thời điểm giám sát kết quả là khác nhau. Trong hình 8, phía bên trái, test-pattern được cung cấp trong khoảng từ T1 đến T2 nhưng kết quả được giám sát trong khoảng từ T3 đến T4.
Xét một ví dụ khác hình 9, mạch này có chức năng "X", đối với kỹ thuật kiểm tra DFT, chúng ta không quan tâm đến chức năng (function) của mạch mà chỉ quan tâm làm thế nào để test dễ dàng một kết nối trong thiết kế nên tác giả gọi đây là mạch "X".
Hình 9: Sơ đồ mạch "X"
Trong mạch X, tương tự, chúng ta xác định được hai nhóm mạch tổ hợp của FF1 và FF2 là com0 và com1. Các kết nối nội bộ như n0, or0, a0, na0, a1 và x0 chỉ có thể được lái bởi ngõ ra của các FF0, FF1 và FF2 nên để test các đường kết nối nội bộ chúng ta phải biết chức năng của mạch để biết khi nào các FF lái đường cần test đến giá trị mong muốn. Thiết kế càng lớn thì việc test theo chức năng mạch sẽ phức tạp và mất thời gian vì khả năng điều khiển (controllable) và giám sát (observable) của các đường kết nối nội bộ càng khó, thậm chí là không thể được. Kỹ thuật DFT sẽ giúp giải quyết vấn đề này.
Như đã phân tích, trong thiết kế các FF là phần tử lưu giữ giá trị và lái các mạch tổ hợp. Ví dụ, để kiểm tra đường a1 của mạch com1 không bị stuck-at-0, a1 cần được lái đến giá trị 1. Trong trường hợp này, các giá trị cấp cho mạch tổ hợp com1 như sau:
  • a1 được lái bằng 1 khi out[1]=1 và n0=1. Trong đó, n0=1 khi FF0./Q=0 bằng cách lái in_0=1.
  • out[2] được lái bằng 0
Sau đó, giám sát giá trị tại x0 phải bằng "1". Nhận xét, việc test a1 sẽ đơn giản nếu các FF (FF0, FF1, FF2) có thể được lái (gán) giá trị dễ dàng. Như vậy, "làm sao để lái giá trị cho các FF khi test mà không phụ thuộc vào chức năng mạch?". Điều này được thực hiện bằng cách thêm một MUX để có thể lựa chọn giá trị cho FF khi cần test như hình 10:
  • test_mode = 0: mạch hoạt động theo chức năng thông thường (user mode)
  • test_mode = 1: giá trị tại chân "?" sẽ được nạp cho các FF. Vấn đề là "?" lấy từ đâu?
Hình 10: Thêm một MUX để điều khiển giá trị của FF khi test
Trong hình 10, chúng ta thấy để lái các FF đến giá trị mong muốn, các MUX phải được thêm vào cho mỗi FF và một chân (pin) mới của chip được sinh ra để điều khiển là chân test_mode. Mỗi dấu "?" có thể được nối đến một chân chip như hình 11. Tuy cách này hoàn toàn có thể thực hiện nhưng khi số lượng FF lớn, nó sẽ làm số chân chip sẽ tăng nên cách này không được sử dụng trên thực tế.
Hình 11: Một cách lái FF khi test_mode=1 nhưng sẽ không được dùng trên thực tế khi số lượng FF quá lớn
Thay vì nạp giá trị cho FF theo cách "song song" như hình 11, chúng ta sẽ nạp theo cách "nối tiếp" như hình 12. Theo cách này, khi test_mode=1, ngõ ra Q của một FF sẽ nối đến ngõ vào D của một FF khác tạo thành một chuỗi FF nối tiếp gọi là chuỗi scan (scan chain) và hoạt động như một thanh ghi dịch (shift regsiter) có đầu vào là scan_in và đầu ra là scan_out.
Hình 12: Mạch logic được áp dụng kỹ thuật DFT
Hình 12 là một ví dụ đặc biệt, trong trường hợp này, chân in_0 có thể dùng làm chân scan_in và MUX ngõ vào của FF0 có thể được loại bỏ. Chân out[2] có thể dùng làm chân scan_out. Như vậy, chip không cần có thêm hai chân mới. Tuy nhiên, trường hợp tổng quát chúng ta sẽ có 3 chân mới là test_mode, scan_in và scan_out.
Hình 13: (a) Mạch không có DFT và (b) có DFT
3) Quá trình test với mạch có DFT
Một chip khi đã áp dụng kỹ thuật DFT, quá trình test sẽ gồm các bước cơ bản sau:
  1. Cung cấp dữ liệu test (test pattern) cho các FF bằng cách lái test_mode=1 và dịch từng bit của test pattern vào chuỗi scan qua chân scan_in theo từng xung clock.
  2. Lấy mẫu (sample, capture) giá trị cần giám sát bằng cách lái test_mode=0 trong 1 chu kỳ xung clock. Giá trị ngõ ra của các mạch tổ hợp được nạp vào các FF trong chuỗi scan.
  3. Thu thập dữ liệu giám sát qua chân scan_out bằng cách lái test_mode=1.
Để test đường a1 không bị stuck-at-0, như đã phân tích chúng ta cần:
  • Lái FF0./Q là 0, tương ứng FF0.Q=1
  • Lái FF1.Q=1
  • Lái FF2.Q=0
Test pattern mong muốn là chuỗi bit 011, 0 được đưa vào trước vì nó dùng để lái FF2 nằm ở cuối chuỗi scan. Dữ liệu giám sát mong muốn là 1XX. Trong đó, "1" là giá trị mong muốn được lấy mẫu từ chân x0 của com1 và lưu trong FF2, còn "X" là giá trị được lưu vào FF1 và FF0. Chú ý, "X" biểu thị ý nghĩa "không quan tâm" (don't care) trong test pattern này chứ không phải là một giá trị bất kỳ hay không xác định.
Hình 14: Mô phỏng kiểm tra lỗi cho đường a1 ở hình 12
Chú ý, thứ tự kết nối các FF trong chuỗi scan có thể được chọn tùy ý chứ không nhất định là FF0->FF1->FF2 như ví dụ minh họa. Nghĩa là chân scan_in có thể đặt ở FF1 hoặc FF2; chân scan_out có thể đặt ở FF0 hoặc FF1. Nhưng khi thay đổi chuỗi scan, thứ tự giá trị của test pattern cũng phải được điều chỉnh tương ứng.
Tóm lại, bài viết này nhắm mục tiêu cung cấp một cái nhìn cơ bản về kỹ thuật DFT. Với kỹ thuật scan, test pattern được đưa vào chân scan_in và giá trị giám sát được lấy trên chân scan_out.
Nếu các bạn có ý kiến cần trao đổi học góp ý, xin comment dưới bài viết hoặc gửi email đến nguyenquan.icd@gmail.com.

Chủ Nhật, 26 tháng 8, 2018

[BUS][Bài 4] Mối quan hệ giữa các kênh trong giao thức AMBA - AXI

Sau khi đăng bài viết số 2 trình bày về các loại burst của giao thức AXI, tác giả có nhận được phản hồi cần minh họa thêm về cơ chế bắt tay VALID/READY nên nội dung bài này sẽ trình bày về mối liên hệ giữa các kênh trong giao thức AXI và những ràng buộc trong giao thức bắt tay hai chiều bằng VALID/READY giữa các kênh.
1) Mối liên hệ giữa các kênh trong giao thức AXI
Giao thức AXI yêu cầu phải duy trì (tuân thủ) ba mối liên hệ sau:
  1. Response của transaction ghi phải theo sau transfer dữ liệu cuối cùng. Nghĩa là sau khi một burst ghi hoàn thành, transfer cuối cùng của burst được phát trên kênh W thì response mới được phát trên kênh B. Response không được phát phát trước transfer cuối cùng của burst. Điều này đảm bảo phía slave phải nhận toàn bộ các transfer dữ liệu của transaction ghi rồi mới được phép phát response. Trên thực tế, để phát một response OKAY, phía slave phải nhận đầy đủ các transfer và xử lý các dữ liệu này mà không bị bất kỳ lỗi nào.
  2. Dữ liệu đọc của một burst phải được phát sau địa chỉ của burst đó. Điều này đảm bảo dữ liệu đọc không tự nhiên sinh ra trên kênh R và phát trước khi có yêu cầu đọc từ phía master trên kênh AR.
  3. Cơ chế bắt tay của các kênh phải tuân thủ quy định về "sự phụ thuộc giữa các tín hiệu bắt tay" (được trình bày ở phần cuối bài này)
Hình 1: Một reponse ghi phải theo sau transfer cuối cùng
Hình 2: Dữ liệu đọc phải theo sau địa chỉ burst
Đối với transaction ghi, dữ liệu ghi trên kênh W có thể xuất hiện trước, cùng lúc hoặc sau địa chỉ ghi trên kênh AW. Trong trường hợp dữ liệu ghi xuất hiện trước địa chỉ ghi, phía slave có thể xử lý theo một trong các cách sau:
  • Tích cực tín hiệu WREADY để nhận dữ liệu ghi và lưu tạm vào thanh ghi (bộ nhớ) đệm. Phía slave chờ cho đến khi nhận được địa chỉ ghi mới bắt đầu thực hiện xử lý dữ liệu ghi đã nhận trước đó. Cách này giúp tối ưu hiệu năng hệ thống nhưng phía slave tốn tài nguyên (logic) để xử lý trường hợp này.
  • Không tích cực tín hiệu WREADY, chờ cho đến khi nhận được địa chỉ ghi trên kênh AW mới bắt đầu tích cực WREADY và nhận dữ liệu trên kênh W. Cách này giúp giảm tài nguyên lưu dữ liệu tạm phía slave nhưng hiệu năng hệ thống bị giảm.

Hình 3: Dữ liệu ghi xuất hiện trước địa chỉ ghi
Hình 4: Dữ liệu ghi và địa chỉ ghi xuất hiện cùng thời điểm
Hình 5: Dữ liệu ghi xuất hiện sau khi địa chỉ ghi được phát
2) Sự phụ thuộc giữa các tín hiệu bắt tay
Như đã trình bày về giao thức bắt tay hai chiều của AXI, Nguyên tắc chung:
  • VALID không được phép phụ thuộc (chờ) READY. Nguồn phải tích cực tín hiệu VALID bất cứ khi nào có thông tin hợp lệ cần truyền mà không được quan tâm đến READY đã tích cực hay chưa. VALID phải được duy trì cho đến khi READY tích cực.
  • Đích chỉ tích cực READY khi nó đã sẵn sàng nhận dữ liệu và READY có thể tích cực trước, trong hoặc sau khi VALID đã tích cực
Tuy AXI cho phép READY có thể chờ VALID tích cực rồi mới đáp ứng nhưng để hệ thống đạt hiệu năng cao nhất, READY nên tích cực bất cứ khi nào phía đích sẵn sàng nhận dữ liệu mà không chờ hay phụ thuộc vào READY.
Hình 6: Ba trường hợp bắt tay giữa VALID và READY
Sự phụ thuộc giữa các tín hiệu bắt tay phải theo nguyên tắc chung đã trình bày trên đây. Mối liên hệ này được biểu diễn bằng một sơ đồ phụ thuộc dùng hai loại đường "mũi tên":
  • Đường mũi tên đơn: Tín hiệu ở cuối mũi tên (ký hiệu E) có thể tích cực trước, cùng lúc hoặc sau khi tín hiệu ở đầu mũi (ký hiệu S) tên tích cực
  • Đường mũi tên kép: Tín hiệu ở cuối mũi tên chỉ được phép tích cực sau khi tín hệu ở đầu mũi tên tích cực.
Chú ý: Sự tích cực của tín hiệu ở đầu mũi tên là "chủ động" và không được phép phụ thuộc vào tín hiệu ở sau mũi tên. S không phụ thuộc vào E.
Hình 7: Quy định về biểu diễn sự phụ thuộc giữa các tín hiệu bắt tay trong AXI
2.1) Sự phụ thuộc giữa các tín hiệu bắt tay của transaction đọc
Hình 8: Sự phụ thuộc giữa các tín hiệu bắt tay của một transaction đọc
Theo hình 8, trong transaction đọc:
  • ARVALID chính là tín hiệu khởi tạo một transaction đọc, phía master tích cực ARVALID bất cứ khi nào cần khởi tạo một transaction đọc mà không được phép chờ ARREADY
  • Phía slave có thể chờ ARVALID rồi mới tích cực ARREADY hoặc có thể tích cực ARREADY trước đó (mối liên hệ được biểu diễn bằng mũi tên đơn)
  • Phía slave phải chờ ARVALID và ARREADY tích cực rồi mới được phép tích cực RVALID (mối liên hệ được biểu diễn bằng mũi tên kép)
  • Phía slave phải tích cực RVALID bất cứ khi nào dữ liệu đọc đã sẵn sàng trên kênh R mà không được chờ RREADY
  • Phía master có thể chờ RVALID rồi mới tích cực RREADY hoặc có thể tích cực RREADY trước RVALID nếu phía master đã sẵn sàng (mối liên hệ được biểu diễn bằng mũi tên đơn)
2.2) Sự phụ thuộc giữa các tín hiệu bắt tay của transaction ghi
Hình 9: Sự phụ thuộc giữa các tín hiệu bắt tay của một transaction ghi trong AXI4
  • Phía master tích cực AWVALID/WVALID mà không được chờ AWREADY hoặc WREADY
  • Phía slave có thể tích cực AWREADY/WREADY trước, cùng lúc hoặc sau  AWVALID hoặc WVALID
  • Phía slave chỉ tích cực BVALID sau khi AWVALID, AWREADY, WVALID and WREADY tích cực. Đồng thời, BVALID chỉ tích cực sau khi WLAST đã tích cực để báo hiệu transfer ghi cuối cùng hoàn thành.
  • Phía slave không được phép chờ BREADY tích cực mới tích cực BVALID.
  • Phía master có thể phát BREADY trước, cùng lúc hoặc sau BVALID.
Trong phiên bản AXI 1.0 (2004), sự phụ thuộc của BVALID vào WLAST, AWVALID và AWREADY không được mô tả. Phiên bản AXI3 cũng không quy định sự phụ thuộc của BVALID vào AWVALID và AWREADY. Điều này có thể làm cho thiết kế slave AXI3 không thể tương thích với AXI4. Cụ thể, vì kênh W và AW hoạt động độc lập nên master có thể phát dữ liệu của một burst ghi trên kênh W trước khi phát địa chỉ trên kênh AW. Trong trường hợp này, phía slave có thể nhận hết các dữ liệu ghi trên kênh W và phát response trước khi phía master phát địa chỉ ghi trên kênh AW. Nếu một slave AXI được thiết kế theo cơ chế này thì nó không thể sử dụng trong hệ thống AXI4. Slave này phải được điều chỉnh lại thiết kế trước khi gắn vào hệ thống AXI4.
Để ngăn chặn sự không tương thích trên, nếu các slave AXI3 được thiết kế mới thì phải tuân thủ những ràng buộc thêm cho BVALID như AXI4.

Hình 10: Waveform chỉ dành cho các phiên bản AXI3 trở về trước, AXI4 không cho phép hoạt động này

Thứ Bảy, 18 tháng 8, 2018

[BUS][Bài 3] Write strobe và unaligned transfer trong giao thức bus AMBA - AXI

Bài này tập trung làm rõ đặc điểm "(2) Hỗ trợ việc trao đổi dữ liệu unaligned và hỗ trợ write strobe" của giao thức AXI đã liệt kê trong bài "Tổng quan về giao thức AMBA - AXI". Trước khi đọc bài này, các bạn nên tham khảo về các loại burst trong giao thức AXI.
1) Write strobe
Write strobe là một thuật ngữ chỉ khả năng có thể điều khiển (chọn) byte dữ liệu hợp lệ trong một transfer dữ liệu khi ghi. Đối với AXI, tín hiệu điều khiển write strobe là WSTRB trên kênh W. Mỗi bit WSTRB điều khiển một byte lane. Trong giao thức AXI một byte lane là một byte (8 bit). Số bit của tín hiệu WSTRB được tính như sau:
Số bit tín hiệu WSTRB = độ rộng bus dữ liệu WDATA/8
Ví dụ, nếu độ rộng bus dữ liệu là 64 bit (8 byte) thì độ rộng WSTRB là 8.
Hình 1: Mối liên hệ giữa WDATA và WSTRB với độ rộng bus dữ liệu là 64 bit
Tổng quát, WSTRB[n] sẽ quản lý WDATA[(n*8)+7:(n*8)] với n = 0, 1, 2, 3, 4, ... Phía master sẽ dùng WSTRB để báo cho phía slave biết byte nào trong bus WDATA là hợp lệ. Quy định:
  • Byte hợp lệ là byte có WSTRB tương ứng bằng 1. Phía slave phải nhận và xử lý byte hợp lệ.
  • Byte không hợp lệ (không được transfer) là byte có WSTRB tương ứng bằng 0. Phía slave không được phép sử dụng giá trị các byte này.
Hình 2 minh họa hoạt động của write strobe trên bus dữ liệu 64 bit, phía master thực hiện các transfer với kích thước bằng với độ rộng bus dữ liệu (AWSIZE = 3). Phía master dùng WSTRB để xác nhận các byte hợp lệ trên bus WDATA.
Phía master có thể tắt một transfer write bằng cách lái tất cả các bit WSTRB bằng 0. Chú ý, transfer bị tắt vẫn được xác nhận bằng một cặp WVALID = WREADY = 1 nhưng slave sẽ không sử dụng dữ liệu này. "Tắt một transfer" không có nghĩa là ngừng các transfer tiếp theo trong burst. Trong giao thức AXI, tất cả các transfer trong một burst phải được thực hiện và transaction phải được hoàn thành đúng theo trình tự mà giao thức đã quy định (tham khảo). AXI không hỗ trợ "ngắt burst sớm" (early termination).
Hình 2: Write strobe trên bus dữ liệu 64 bit
Phân tích trên đây đã giải thích về write strobe, một phần của đặc điểm "(2) Hỗ trợ việc trao đổi dữ liệu unaligned và hỗ trợ write strobe".
Tuy mỗi bit WSTRB quản lý một byte của WDATA nhưng nó không hoạt động độc lập mà có liên hệ với các thuộc tính khác của burst. Các thuộc tính liên hệ trực tiếp đến WSTRB gồm:
  1. AWADDR: Địa chỉ bắt đầu (Start address)
  2. AWBURST: Kiểu burst
  3. AWSIZE: Kích thước tối đa của một transfer trong burst
Điều này sẽ được phân tích ở những phần sau trong bài này.
2) Aligned và Unaligned
Địa chỉ aligned là những địa chỉ tuân theo giới hạn biên được quy định bởi AxSIZE.
Hình 3: Cách xác định các địa chỉ aligned
Xét hình 3, khi AxSIZE = 0, kích thước mỗi transfer là 1 byte, tất cả các giá trị địa chỉ đều gọi là aligned theo byte. Khi AxSIZE > 0, địa chỉ aligned là địa chỉ có các bit LSB bằng 0 tương ứng với giá trị của AxSIZE. Ví dụ nếu AxSIZE = 3, kích thước mỗi transfer là 8 byte thì địa chỉ aligned là những địa chỉ có AxADDR[2:0] = 0, ví dụ như 0x0000, 0x0008, 0x0010, ...
Địa chỉ unaligned là những địa chỉ không tuân theo giới hạn biên được quy định bởi AxSIZE. Không tồn tại giá trị địa chỉ unaligned cho trường hợp AxSIZE = 0, kích thước mỗi transfer là 1 byte. Khi AxSIZE > 0, địa chỉ unaligned sẽ có các bit LSB khác 0 tương ứng với giá trị của AxSIZE. Ví dụ nếu AxSIZE = 3, kích thước mỗi transfer là 8 byte thì địa chỉ unaligned là những địa chỉ có AxADDR[2:0] khác 0, ví dụ như 0x0001, 0x0002, 0x0003, ...
Hình 4: Ví dụ về địa chỉ aligned và unaligned
AXI chỉ phát một địa chỉ bắt đầu cho mỗi transfer và nó cho phép địa chỉ này có thể là địa chỉ unaligned.
Đối với kiểu burst FIXED, khi phía master phát một địa chỉ unaligned thì địa chỉ này sẽ áp dụng cho tất cả các transfer trong burst.
Hình 5: Địa chỉ unaligned trong kiểu burst FIXED, độ rộng bus dữ liệu là 32 bit, mỗi hàng là 1 transfer, ô màu xám là dữ liệu không được transfer
Đối với kiểu burst INCR, địa chỉ unaligned sẽ chỉ áp dụng cho transfer đầu tiên của burst, địa chỉ của những transfer khác trong burst là địa chỉ aligned. Xét ví dụ hình 5:
  • Với địa chỉ unaligned 0x01 thì byte ở vị trí địa chỉ 0x00 sẽ không được phía master transfer, phía slave sẽ không được phép sử dụng byte này.
  • Với địa chỉ unaligned 0x07 thì các byte ở vị trí địa chỉ 0x04, 0x05 và 0x06 sẽ không được phía master transfer.
Hình 6: Minh họa về aligned và unaligned cho bus dữ liệu 32 bit, kiểu burst INCR, mỗi hàng là một transfer, những ô màu xám là các byte dữ liệu không được transfer (không hợp lệ)
Hình 7 là một minh họa khác về aligned và unaligned cho kiểu INCR với bus dữ liệu 64 bit nhưng kích thước transfer chỉ là 32 bit.
Hình 7: Minh họa về aligned và unaligned cho bus dữ liệu 64 bit, kiểu burst INCR, mỗi hàng là một transfer, những ô màu xám là các byte dữ liệu không được transfer (không hợp lệ)
Đối với kiểu WRAP, chỉ các địa chỉ aligned được phép sử dụng.
Hình 8: Minh họa về aligned cho bus dữ liệu 64 bit, kiểu burst WRAP, mỗi hàng là một transfer, những ô màu xám là các byte dữ liệu không được transfer (không hợp lệ)
Đến đây, toàn bộ đặc điểm "(2) Hỗ trợ việc trao đổi dữ liệu unaligned và hỗ trợ write strobe" đã được mô tả.
3) Sự ràng buộc giữa WSTRB và thuộc tính của burst
Như đã nói ở phần 1 của bài này, WSTRB không hoạt động độc lập, WSTRB phải được lái các giá trị phù hợp với kiểu burst, địa chỉ bắt đầu và kích thước transfer. Nguyên tắc chung là WSTRB không được phép tích cực (bằng 1) tại các byte không được transfer (byte không hợp lệ).
Hình 9 minh họa giá trị WSTRB trong kiểu burst FIXED và địa chỉ unaligned, WSTRB[0] luôn bằng 0 vì byte 0x00 là byte không được transfer.
Hình 9: WSTRB trong kiểu burst FIXED và địa chỉ unaligned, bus dữ liệu là 32 bit và kích thước transfer là 32 bit
Hình 10 và hình 11 minh họa giá trị WSTRB trong kiểu burst INCR với địa chỉ aligned và unaligned, WSTRB tại các vùng dữ liệu không sử dụng luôn bằng 0.
Hình 10: WSTRB trong kiểu burst INCR và địa chỉ aligned, bus dữ liệu là 64 bit và kích thước transfer là 32 bit
Hình 11: WSTRB trong kiểu burst INCR và địa chỉ unaligned, bus dữ liệu là 64 bit và kích thước transfer là 32 bit
Kiểu burst WRAP cũng áp dụng nguyên tắc tương tự nên tác giả không minh họa thêm. Như vậy, kiểu burst, địa chỉ bắt đầu và kích thước transfer quyết định byte nào trên bus dữ liệu là hợp lệ (được transfer) nhưng thông tin này và giá trị WSTRB phải phù hợp với nhau.
4) Nhận xét
Trong một hệ thống, nếu phía master luôn phát các dữ liệu hợp lệ có kích thước bằng độ rộng bus dữ liệu WDATA thì có thể lái toàn bộ tín hiệu WSTRB = 1 hoặc không cần tạo ra WSTRB nhưng phía slave phải gán cố định tất cả các tín hiệu WSTRB = 1.
Hình 12: Kết nối trong trường hợp phía master luôn phát dữ liệu hợp lệ có kích thước bằng độ rộng bus dữ liệu
Việc sử dụng địa chỉ unaligned có thể được thay thế bằng một địa chỉ aligned kết hợp với điều khiển WSTRB. Byte nào không muốn transfer thì WSTRB của nó sẽ được gán giá trị 0. Xét lại hình 9, thay vì phát một địa chỉ unaligned lad 0x01, phía master có thể phát một địa chỉ aligned 0x00 nhưng luôn lái WSTRB[0] = 0 cho mỗi transfer dữ liệu.
Transaction đọc cũng có thể sử dụng địa chỉ unaligned nhưng điều này là không cần thiết. Thông thường phía slave sẽ trả đầy đủ các byte dữ liệu trên RDATA cho mỗi transfer đọc, việc sử dụng byte nào là tùy phía master.

Tham khảo:

1. ARM, AMBA® AXI™ and ACE™ Protocol Specification, 2011

Thứ Tư, 15 tháng 8, 2018

[BUS][Bài 2] Các loại burst của giao thức AMBA - AXI

Tiếp theo bài 1, bài này sẽ mô tả chi tiết các loại burst trong transaction của AXI với sơ đồ timing cụ thể. Mục tiêu là làm rõ đặc điểm "(3) Hỗ trợ các transaction theo cơ chế burst và chỉ cần phát địa chỉ đầu tiên của burst".

1) Cơ chế bắt tay hai chiều (two-way) của AXI 

Giao thức AXI hoạt động dựa trên cơ chế bắt tay hai chiều (two-way handshake) sử dụng một tín hiệu VALID và một tín hiệu READY. 
Nguồn phát (source) sẽ sử dụng tín hiệu VALID để báo hiệu một địa chỉ, thông tin điều khiển hoặc dữ liệu đã hợp lệ trên kênh truyền. VALID giống như tín hiệu yêu cầu (request) một đích (destination) nhận thông tin. 
Đích (destination) sẽ sử dụng tín hiệu READY để thông báo cho nguồn biết nó đã chấp nhận thông tin từ source. READY giống như tín hiệu ACK xác nhận yêu cầu (request) từ nguồn. 
Nguồn và đích có thể là master hoặc slave. Ví dụ, trong một transaction đọc, trên kênh AR, phía master là nguồn phát địa chỉ và thông tin điều khiển, phía slave là đích. Vì vậy, phía master sẽ điều khiển tín hiệu VALID, phía slave sẽ điều khiển tín hiệu READY. Đối với kênh R thì ngược lại, slave là nguồn phát dữ liệu đọc, còn master là đích nên slave sẽ điều khiển VALID còn master điều khiển READY. 
Mỗi kênh sẽ có một cặp VALID/READY gọi là cặp tín hiệu bắt tay để hoạt động theo cơ chế này. Cụ thể: 
  • Kênh AR sẽ có tín hiệu ARVALID (master) và tín hiệu ARREADY (slave) 
  • Kênh R sẽ có tín hiệu RVALID (slave) và tín hiệu RREADY (master) 
  • Kênh AW sẽ có tín hiệu AWVALID (master) và tín hiệu AWREADY (slave) 
  • Kênh W sẽ có tín hiệu WVALID (master) và tín hiệu WREADY (slave) 
  • Kênh B sẽ có tín hiệu BVALID (slave) và tín hiệu BREADY (master) 
*Chú ý: trong bài viết, VALID được hiểu là ARVALID, AWVALID, RVALID hoặc WVALID. READY được hiểu là ARREADY, AWREADY, RREADY hoặc WREADY.
Nguyên tắc chung: 
  • Nguồn phải tích cực tín hiệu VALID bất cứ khi nào có thông tin hợp lệ cần truyền mà không được quan tâm READY đã tích cực hay chưa. VALID phải được duy trì cho đến khi READY tích cực.
  • Đích chỉ tích cực READY khi nó đã sẵn sàng nhận dữ liệu và READY có thể tích cực trước, trong hoặc sau khi VALID đã tích cực.
Hình 1: Cơ chế bắt tay hai chiều của giao thức AXI
Hình 6 minh họa cơ chế bắt tay hai chiều của AXI: 
  • Tại T0: nguồn tích cực VALID báo có thông tin hợp lệ trên kênh truyền (kênh AR, AW, R hoặc kênh W). 
  • Từ T0 đến T2: VALID phải được duy trì mức tích cực vì đích không sẵn sàng (READY = 0) để nhận thông tin lúc này. 
  • Tại T2: Đích tích cực READY báo hiệu đã sẵn sàng nhận thông tin. 
  • Tại T3: Khi VALID và READY cùng tích cực, đích nhận thông tin và nguồn cũng biết điều này. Nếu nguồn tiếp tục có thông tin hợp cần truyền nó sẽ duy trì VALID = 1 sau T3. Nếu nguồn không có thông tin mới cần truyền nó sẽ thôi tích cực VALID như hình 6
  • Sau T3: Đích vẫn duy trì tín hiệu READY để báo hiệu nó đã sẵn sàng nhận thêm thông tin mới như hình 6. Nếu đích đang bận xử lý nhiệm vụ khác, chưa thể nhận thêm thông tin mới, nó sẽ thôi tích cực READY.
*Chú ý: Ở đây, "Thông tin" là địa chỉ, thông tin control hoặc dữ liệu tùy vào kênh.
Nguồn không được phép chờ READY tích cực rồi mới tích cực VALID. nó phải chủ động tích cực VALID bất cứ khi nào phát thông tin hợp lệ lên kênh truyền. Điều này giống như việc bạn phải chủ động báo cáo cho sếp khi đã hoàn thành công việc chứ không chờ sếp hỏi mới báo cáo.
Đích có thể chờ cho VALID tích cực rồi mới tích cực READY. Điều này giống như việc khi sếp đã nhận báo cáo của bạn nhưng kiểm tra báo cáo lúc nào là việc của sếp. Sếp kiểm tra xong sẽ phản hồi lại cho bạn. Tuy nhiên cách làm này sẽ làm giảm hiệu năng hệ thống. Vì vậy, nếu có thể, đích luôn tích cực READY bất cứ khi nào nó có khả năng nhận thông tin mới từ nguồn. Điều này giống như việc, sếp sẽ chủ động nói với bạn "anh đang chờ đọc báo cáo của em" khi sếp rảnh và bạn biết được nếu báo cáo được nộp lúc đó thì báo cáo sẽ được sếp đọc ngay.
Với cơ chế bắt tay hai chiều, mỗi kênh có thể hoàn thành transfer của nó một cách độc lập để tiếp tục thực hiện transfer tiếp theo mà không cần chờ kênh khác.
Hình 2: Cơ chế bắt tay hai chiều VALID/READY cho phép các transfer trên một kênh có thể hoàn thành độc lập với kênh khác
Hình 2, trên kênh AR, transfer địa chỉ và control của transaction B được phát ngay sau khi transfer địa chỉ và control của transaction A hoàn thành bất chấp các transfer dữ liệu và response của transaction A vẫn chưa hoàn thành trên kênh R.
2) Cơ chế burst transaction
Phần này sẽ tập trung giải thích đặc tính "(3) Hỗ trợ các transaction theo cơ chế burst và chỉ cần phát địa chỉ đầu tiên của burst" của giao thức AXI. AXI là giao thức dựa trên cơ chế burst, mỗi transaction điều khiển một burst nên transaction còn được gọi đầy đủ là burst transaction. Đặc tính của burst được quy định bởi thông tin điều khiển truyền trên kênh AR/AW.
Để khởi động một transaction, phía master sẽ phát địa chỉ và thông tin điều khiển của transaction trên kênh AR hoặc AW. Trong đó:
  • Địa chỉ được phát là địa chỉ của byte đầu tiên trong một transaction.
  • Thông tin điều khiển gồm thông tin quy định thuộc tính của burst và các thuộc tính khác của transasion.
Trong giao thức AXI, phía master không phát các địa chỉ trung gian của các beat trong một burst mà chỉ phát địa chỉ byte đầu tiên trong một transaction, đây chính là địa chỉ của transfer dữ liệu đầu tiên. Phía slave dựa trên thông tin điều khiển để xác định địa chỉ của các beat từ địa chỉ đầu tiên này. Điều này giúp tăng performance của hệ thống bus nhưng làm mạch logic xử lý giao tiếp AXI tại phía slave phức tạp hơn vì phải tự tính toán các địa chỉ beat.
So sánh với giao thức bus APB (Advanced Peripheral Bus), một địa chỉ cụ thể chỉ ứng với một dữ liệu được đọc hoặc ghi. Điều này làm cho mạch logic xử lý giao tiếp APB đơn giản, chỉ cần giải mã địa chỉ có sẵn để sử dụng, nhưng hiệu năng bus là không cao.
Để giải thích cơ chế burst transaction, chúng ta tập trung vào các tín hiệu địa chỉ và điều khiển tại mỗi kênh như sau:
  • Kênh AR/AW
    • AxADDR (ARADDR/AWADDR) Địa chỉ của transfer dữ liệu đầu tiên của transaction.
    • AxLEN (ARLEN/AWLEN) Độ dài burst. Thông tin điều khiển này xác định số transfer dữ liệu trong burst, là số beat trong burst.
    • AxSIZE (ARSIZE/AWSIZE) Kích thước burst. Thông tin điều khiển này xác định kích thước chung của mỗi transfer dữ liệu trong burst.
    • AxBURST (ARBURST/AWBURST) Loại burst. Thông tin điều khiển này xác định phương pháp, cơ chế tính địa chỉ cho mỗi transfer dữ liệu (mỗi beat) trong burst.
    • AxVALID (ARVALID/AWVALID) Tín hiệu VALID của kênh địa chỉ.
    • AxREADY (ARREADY/AWREADY) Tín hiệu READY của kênh địa chỉ.
  • Kênh R
    • RDATA Dữ liệu đọc
    • RLAST Tín hiệu báo transfer dữ liệu (beat) cuối cùng trong một burst đọc.
    • RRESP Tín hiệu báo trạng thái của các transfer đọc.
    • RVALID Tín hiệu VALID của kênh R
    • RREADY Tín hiệu READY của kênh R
  • Kênh W
    • WDATA Dữ liệu ghi
    • WLAST Tín hiệu báo transfer dữ liệu (beat) cuối cùng trong một burst ghi.
    • WVALID Tín hiệu VALID của kênh W
    • WREADY Tín hiệu READY của kênh W
  • Kênh B
    • BRESP Tín hiệu báo trạng thái của transaction ghi.
    • BVALID Tín hiệu VALID của kênh B
    • BREADY Tín hiệu READY của kênh B
Hình 3: Nhóm tín hiệu dùng cho việc giải thích burst transaction đọc
Hình 4: Nhóm tín hiệu dùng để giải thích cho burst transaction ghi
*Chú ý: Ở đây, tác giả không liệt kê toàn bộ các tín hiệu của mỗi kênh mà chỉ tập trung giải thích cơ chế burst transaction. Chi tiết về các tín hiệu giao tiếp của mỗi kênh được mô tả trong tài liệu chuẩn.

Độ dài một burst (số beat) được quy định bởi AxLEN và tính như sau:
Độ dài burst (số beat) = AxLEN + 1
Số byte tối đa của một transfer dữ liệu (một beat) được quy định bởi AxSIZE. Kích thước này không được lớn hơn độ rộng bus dữ liệu (độ rộng RDATA/WDATA). Ví dụ, bus dữ liệu có độ rộng 32 bit thì AxSIZE[2:0] phải nhỏ hơn hoặc bằng 5.
Hình 5: Bảng giá trị của AxSIZE (ARSIZE/AWSIZE)
Loại burst được xác định bởi AxBURST. AXI hỗ trợ 3 loại burst là:
  • FIXED: Địa chỉ của mỗi transfer dữ liệu trong transaction là như nhau.
  • INCR: Địa chỉ của một transfer dữ liệu trong burst bằng địa chỉ của transfer trước đó tăng thêm một giá trị được quy định bởi AxSIZE. Ví dụ, AxSIZE[2:0] = 2, số byte của một transfer là 4 thì địa chỉ của transfer hiện tại bằng địa chỉ transfer trước tăng 4.
  • WRAP: Địa chỉ của một transfer dữ liệu trong burst bằng địa chỉ của transfer trước đó tăng thêm một giá trị được quy định bởi AxSIZE nhưng chỉ các bit địa chỉ LSB được tăng. Số lượng bit LSB được tăng phụ thuộc vào AxLEN và AxSIZE. Ví dụ, khi AxLEN = 7, số transfer dữ liệu là 8, nếu AxSIZE = 2 (4 byte) thì số bit LSB được tăng là 5. Nghĩa là địa chỉ của transfer hiện tại sẽ bằng địa chỉ của transfer trước với 5 bit LSB [4:0] được cộng thêm 4. Chú ý, các bit địa chỉ [*:5] sẽ không đổi.
    • Địa chỉ bắt đầu phải aligned theo AxSIZE
    • AxLEN phải bằng 1, 3, 7, 15 ứng với độ dài burst là 2, 4, 8 và 16 beat.
Hình 6: Bảng giá trị của AxBURST (ARBURST/AWBURST)
Loại response được xác định bằng giá trị trên RRESP và BRESP. AXI hỗ trợ 4 loại response:
Hình 7: Bảng giá trị của RRESP/BRESP
3) Kiểu burst FIXED
3.1) Ví dụ
Hình 8: Transaction đọc với kiểu FIXED burst
Hình 8 là một ví dụ về transaction đọc với kiểu burst FIXED. Thông số của transaction này như sau:
  • Địa chỉ bắt đầu: 0x1238
  • Độ dài burst là 8 với ARLEN[7:0] = 0x07
  • Kích thước mỗi beat là 4 byte với ARSIZE[2:0] = 0b010
  • Loại burst là FIXED với ARBURST[1:0] = 0b00
Giải thích waveform hình 8:
  • Kênh AR:
    • T0: Phía master tích cực tín hiệu ARVALID = 1 để báo hiệu cần thực hiện một transaction đọc. Địa chỉ đầu tiên của transaction (ARADDR) và các thông tin về burst (ARLEN, ARSIZE, ARBURST) phải được cung cấp ổn định trong suốt quá trình ARVALID tích cực.
    • T0 đến T1: Phía slave chưa sẵn sàng đáp ứng yêu cầu của phía master nên giữ ARREADY = 0.
    • T1: Phía slave sẵn sàng nhận thông tin về transaction của phía master nên tích cực AREADY = 1.
    • T2: Phía slave nhận thông tin về transaction đọc của phía master. Phía slave thôi tích cực AREADY vì không sẵn sàng nhận thêm yêu cầu mới (phía slave có thể giữ ARREADY = 1 nếu vẫn có thể tiếp tục nhận thêm yêu cầu transaction mới). Phía master thôi tích cực ARVALID vì không có thêm yêu cầu mới tiếp theo (phía master có thể tiếp tục giữ ARVALID = 1 nếu vẫn muốn phát tiếp yêu cầu transaction mới).
  • Kênh R:
    • Nếu phía slave có thể đáp ứng transaction đọc, nó sẽ tích cực ARVALID = 1 kèm theo dữ liệu RDATA và trạng thái của transfer đọc RRESP. Thời gian từ T6 đến T7 là khoảng thời gian phía slave chưa có dữ liệu đọc để gửi.
    • Từ T8 đến T9, phía slave gửi một RRESP là SLVERR để báo hiệu transfer đọc này bị lỗi.
    • Từ T10 đến T11, phía slave gửi transfer đọc cuối cùng nên tích cực thêm tín hiệu RLAST = 1.
    • Phía master sẽ tích cực tín hiệu RREADY bất cứ khi nào nó sẵn sàng nhận transfer đọc. Trên waveform, phía master sẽ nhận các transfer đọc tại các thời điểm T3, T4, T5, T6, T8, T9, T10 và T11.
Do đây là kiểu burst FIXED nên địa chỉ của các dữ liệu D0 đến D7 đều giống nhau và bằng địa chỉ bắt đầu 0x1238.
Hình 9. Transaction ghi với kiểu burst FIXED
Hình 9 là một minh họa về waveform của transaction ghi với kiểu burst là FIXED. Khác với transaction đọc, response của transaction ghi chỉ được gửi 1 lần sau khi đã kết thúc burst trên kênh B.
3.2) Ứng dụng
Kiểu burst FIXED sử dụng để truy cập nhiều lần vào cùng một địa chỉ. Nó có thể dùng để truy xuất FIFO/LIFO. Mỗi transfer đọc/ghi sẽ tác động làm tăng giá trị con trỏ đọc/ghi của FIFO/LIFO.
Hình 10: Minh họa về sự sử dụng kiểu burst FIXED để truy xuất FIFO
Hình 10 minh họa về việc sử dụng kiểu FIXED burst truy xuất FIFO. Ở đây, địa chỉ của kênh AR/AW sẽ được lưu lại trong thanh ghi và dùng để giải mã tín hiệu đọc/ghi. Tín hiệu đọc ghi được tạo ra khi VALID và READY trên kênh R/W cùng tích cực. Khi tín hiệu đọc/ghi tích cực thì dữ liệu sẽ được đọc ra/ghi vào FIFO và giá trị con trỏ đọc/ghi sẽ được tăng lên.
4) Kiểu burst INCR
4.1) Ví dụ
Hình 11: Transaction đọc kiểu burst INCR
Hình 12: Transaction ghi kiểu burst INCR
4.2) Ứng dụng
Kiểu burst INCR được dùng phổ biến truy cập đến các vùng địa chỉ liên tiếp nhau như bộ nhớ hoặc các nhóm thanh ghi có địa chỉ liên tục.
Hình 13: Một bộ nhớ có địa chỉ liên tục có thể truy xuất dễ dàng bởi burst INCR
5) Kiểu burst WRAP
5.1) Ví dụ
Hình 14: Transaction đọc với kiểu burst WRAP
Hình 15: Transaction ghi với kiểu burst WRAP
5.2) Ứng dụng
Kiểu burst WRAP sử dụng để truy xuất cache line. Trong hệ thống tốc độ cao CPU không truy xuất trực tiếp bộ nhớ chính (main memory) vì tốc độ đọc/ghi chậm mà sử dụng bộ nhớ trung gian là cache. Nếu trong quá trình hoạt động, cache không chứa giá trị mà CPU cần, gọi là bị "miss", thì nó sẽ bắt đầu tìm giá trị bị "miss" từ bộ nhớ chính.
Dữ liệu được lấy từ bộ nhớ chính theo từng block có kích thước cố định gọi là một "cache line" hoặc "cache block". Mỗi cache line gồm nhiều ô nhớ có địa chỉ liên tục. Có hai cách lấy một cache line là:
  • Early restart: lấy theo thứ tự cache line từ địa chỉ đầu tiên đến địa chỉ cuối cùng của block đến khi gặp giá trị bị "miss" thì gửi giá trị này đến CPU để CPU tiếp tục xử lý. Để làm điều này, CPU dùng kiểu truy xuất INCR.
  • Critical word first: lấy bắt đầu từ giá trị bị miss, giá trị này gọi là "critical word", để có thể gửi nó đến CPU sớm, sau đó tiếp tục lấy những giá trị còn lại trong block (cache line). Để làm được điều này, CPU dùng kiểu truy xuất WRAP.
Hình 16: Minh họa ứng dụng của kiểu burst WRAP trong truy xuất cache line

Tóm lại, bài này tập trung phân tích hoạt động trao đổi dữ liệu của AXI dựa trên cơ chế burst và làm rõ các ứng dụng của từng kiểu burst.