Thứ Sáu, 25 tháng 8, 2017

[Multi-clock Design] Bài 2 - Kỹ thuật đồng bộ tín hiệu điều khiển giữa các miền clock bất đồng bộ

Bài này mô tả các kỹ thuật được sử dụng để đồng bộ tại giao tiếp của các miền clock bất đồng bộ. Mỗi trường hợp cụ thể, kỹ thuật sử dụng để thiết kế mạch đồng bộ sẽ khác nhau nhưng đều nhằm hai mục đích chính là hạn chế sự lan truyền của trạng thái bất ổn định (metastability) và lấy mẫu đúng giá trị mong muốn ở ngõ vào bất đồng bộ.
Trước khi đọc bài này, các bạn hãy đọc kỹ bài viết sau vì nhiều khái niệm sử dụng sẽ không được nhắc lại.

http://nguyenquanicd.blogspot.com/2017/08/multi-clock-design-bai-1-ky-thuat-thiet.html

1. Kỹ thuật đảm bảo độ rộng tín hiệu bất đồng bộ

1.1 Đảm bảo độ rộng tín hiệu dựa trên tỷ lệ của tần số xung clock

Việc đồng bộ tín hiệu 1 bit sử dụng 2 hoặc nhiều Flip-Flop (FF) chỉ đảm bảo hạn chế trạng thái bất ổn định (metastability state) lan truyền trong thiết kế chứ không đảm bảo nhận (lấy mẫu) đúng dữ liệu ngõ vào mong muốn ở ngõ vào do 2 yếu tố:
  1. Cạnh tích cực (trong bài này minh họa theo cạnh lên xung clock) của xung clock nhận chưa chắc bắt đúng được vị trí có giá trị mong muốn của ngõ vào vì ngõ vào thay đổi bất cứ khi nào không phụ thuộc vào xung clock nhận.
  2. Cạnh tích cực của clock nhận có thể bắt được giá trị thay đổi của ngõ vào nhưng có thể vi phạm định thời (timing) và gây ra trạng thái bất ổn định làm cho giá trị ngõ ra có thể ổn định về một giá trị logic không xác định trước
Do đó, việc sử dụng mạch đồng bộ mắc nối tiếp dùng nhiều FF cần có những tín toán và ràng buộc thêm để đảm bảo lấy đúng được dữ liệu ngõ vào mong muốn. Hình sau sẽ được dùng để phân tích về vấn đề này.
Hình 1. Mạch đồng bộ tín hiệu 1 bit dùng 2 FF
Điểm chính của vấn đề là mối liên hệ giữa độ rộng tín hiệu d_outa và xung clock clk_b. d_outa là tín hiệu thay đổi giá trị theo xung clock clk_a và bất đồng bộ với xung clock clk_b.

Trường hợp xung clock clk_a có tần số thấp hơn tần số xung clock clk_b, độ rộng* tối thiểu của tín hiệu d_outa nhỏ hơn chu kỳ xung clock clk_b. Việc lấy mẫu đúng được dữ liệu d_outa gần như là bất khả thi.
Hình 2. Độ rộng tín hiệu ngõ vào nhỏ hơn chu kỳ xung clock nhận làm cho xung clock clk_b không thể lấy mẫu đầy đủ các giá trị ở ngõ vào d_outa
Trường hợp xung clock clk_a cùng tần số với xung clock clk_b, lúc này độ rộng tín hiệu d_outa bằng độ rộng xung clk_b nhưng vẫn không đảm bảo clk_b có thể lấy mẫu đúng d_outa vì độ lệch pha giữa clk_a và clk_b là không biết trước nên tín hiệu d_outa sinh ra hoàn toàn có thể vi phạm định thời clk_b.
Hình 3. Độ rộng tín hiệu ngõ vào d_outa bằng chu kỳ xung clock clk_b vẫn không đảm bảo lấy mẫu đúng dữ liệu
Tổng quát, nếu độ rộng tín hiệu d_outa, ký hiệu td_outa, nhỏ hơn hoặc bằng tổng chu kỳ clk_b (Tclk_b) cộng setup time (tsu) và hold time (th) của clk_b thì vấn đề xảy ra giống như trường hợp hình 3.

Xét trường hợp sau:
td_outa > Tclk_b + tsu + th

Hình 4 (A) minh họa độ rộng tối thiểu của ngõ vào bất đồng bộ d_outa lớn hơn Tclk_b + tsu + th.
Hình 4 (B) minh họa sự kiện chuyển trạng thái từ mức 0 lên mức 1 của d_outa bị vi phạm timing và làm cho d_outb đạt đến giá trị không mong muốn ở cạnh lên xung clock đầu tiên nhưng ở cạnh xung clock clk_b thứ 2, d_outb cập nhật đúng giá trị ngõ vào mong muốn. Đến cạnh xung clock thứ 3, ngõ ra mạch đồng bộ là d_outc sẽ thể hiện được giá trị mới của ngõ vào d_outa.
Hình (C) thể hiện việc 1 giá trị logic của ngõ vào d_outa có thể được thể hiện ở ngõ ra trong 2 chu kỳ dù giá trị ngõ vào không tồn tại trong khoảng thời gian 2 chu kỳ. Tuy nhiên, bất cứ thay đổi nào của ngõ vào d_outa đều được thể hiện ở ngõ ra d_outc của mạch đồng bộ:
  • d_outa chuyển từ mức 0 lên mức 1 thì chắc chắn d_outc cũng sẽ chuyển từ mức 0 lên mức 1
  • d_outa chuyển từ mức 1 xuống mức 0 thì chắc chắn là d_outc cũng sẽ chuyển từ mức 1 lên mức 0
Hình 4. Mạch đồng bộ bắt được tất cả các sự kiện đổi trạng thái ngõ vào khi độ rộng tín hiệu bất đồng bộ d_outa lớn hơn Tclk_b + tsu + th
Tóm lại, nếu độ rộng tín hiệu bất đồng bộ lớn hơn Tclk_b + tsu + th thì mạch đồng bộ luôn bắt được tất cả các sự kiện chuyển trạng thái, từ 0 lên 1 hoặc từ 1 xuống 0, của d_outa. Chú ý, mạch đồng bộ phát hiện và báo đúng các sự kiện chuyển trạng thái chứ không phải thể hiện đúng độ rộng của giá trị ngõ vào.

Ví dụ, nếu miền xung clock clk_a cần phát một tín hiệu điều khiển bật/tắt (ON/OFF) một chức năng nào đó sang miền xung clock clk_b với chu kỳ các xung clock biết trước thì nó có thể sử dụng cạnh lên để ON, cạnh xuống để OFF. Tín hiệu này cần duy trì với độ rộng như ràng buộc trên đây. Giả sử, tần số clk_a là 75 Mhz ứng với chu kỳ 13.333ns; tần số xung clock clk_b là 25 Mhz ứng với chu kỳ 40ns; setup time của D-FF trên clk_b là 1ns, hold time của D-FF trên clk_b là 2ns. Để miền clock clk_b có thể bắt được các sự kiện điều khiển từ clk_a thì d_outa có độ rộng như sau:

td_outa > 40 + 1 + 2 (ns)
td_outa > 43 (ns)

d_outa có thể được thiết kế bằng cách duy trì trong 4 xung clock clk_a ứng với độ rộng:
td_outa ≈ 4 x 13.333 ≈ 53.333

Do độ rộng của một giá trị logic ở ngõ ra mạch đồng bộ (d_outc) không cố định do ảnh hưởng của hiện tượng bất ổn định nên một mạch phát hiện cạnh được sử dụng để phát hiện sự kiện chuyển trạng thái và báo hiệu trong 1 chu kỳ xung clock.
Hình 5. Mạch phát hiện cạnh của tín hiệu ngõ ra mạch đồng bộ
Hình 6. Dạng sóng minh họa hoạt động của mạch hình 5
Quan sát dạng sóng ví dụ, khi xảy ra trạng thái bất ổn định trên d_outb, tùy vào giá trị ổn định sau đó của d_outb là "0" hoặc "1" mà ngõ ra mạch đồng bộ là d_outc sẽ khác nhau làm cho ví trí báo hiệu của xung falling_edge sẽ khác nhau.

Cách đảm bảo độ rộng tín hiệu trên đây yêu cầu cần biết trước tần số xung clock nhận để miền phát có thể tạo được độ rộng xung phù hợp. Nếu miền xung clock phát chỉ tạo một độ rộng xung cố định thì phải giới hạn tần số miền xung clock nhận cho phù hợp.

1.2 Đảm bảo độ rộng tín hiệu bất đồng bộ bằng phương pháp hồi tiếp

Phương pháp này sử dụng ngõ ra mạch đồng bộ của miền clock nhận để hồi tiếp lại miền xung clock phát. Miền clock phát sẽ nhận tín hiệu hồi tiếp, đồng bộ lại theo xung clock miền phát để điều khiển độ rộng tín hiệu gửi sang miền clock nhận.
Hình 7. Đảm bảo độ rộng xung bằng phương pháp hồi tiếp
Hình trên minh họa việc miền xung clock clk_a (miền phát) gửi tín hiệu req tích cực mức "1" sang miền xung clock clk_b (miền nhận). Tín hiệu req sau khi được đồng bộ ở miền xung clock clk_b để tạo ra tín hiệu sync_req thì sync_req sẽ được hồi tiếp lại miền xung clock clk_a. Tín hiệu hồi tiếp sẽ được đồng bộ lại theo xung clock clk_a trước khi đi qua khối tạo tín hiệu xóa req là REG_CLR. Như vậy, khi req tích cực nó sẽ duy trì mức tích cực đến khi khối REQ_CLR nhận được đúng giá trị req đã hồi tiếp về, nghĩa là đã đảm bảo miền xung clock clk_b nhận được req, thì mới thôi tích cực req.

Phương pháp hồi tiếp này không cần quan tâm đến mối liên hệ giữa tần số clk_a và clk_b vì độ rộng tín hiệu req ở miền xung clock clk_a được duy trì cho đến khi biết chắc chắn miền xung clock clk_b đã nhận req.

2. Đồng bộ nhiều tín hiệu điều khiển

Đồng bộ nhiều tín hiệu giữa hai miền clock bất đồng bộ có một số điểm cần phải lưu ý hơn so với việc đồng bộ một tín hiệu như đã trình bày trên đây. Việc đồng bộ nhiều tín hiệu không phải chỉ cần dùng 2 hay nhiều FF mắc nối tiếp là được. Một số ví dụ sau đây sẽ giải thích tại sao việc chỉ dùng 2 hay nhiều FF mắc nối tiếp là không đảm bảo.

2.1 Đồng bộ hai tín hiệu hoạt động song song

Ví dụ, một giao tiếp cần truyền hai tín hiệu điều khiển từ miền xung clock clk_a sang miền xung clock clk_b như sau:

  • sel là tín hiệu lựa chọn tích cực mức 1 khi miền clock clk_a cần truyền dữ liệu cho miền clock clk_b
  • enable là tín hiệu tích cực mức 1 khi có dữ liệu hợp lệ
  • data_in là bus dữ liệu 
Hình 8. Một mạch đồng bộ các tín hiệu điều khiển không đúng
Trong hình trên, hai tín hiệu điều khiển sel và enable được đồng bộ thông qua mạch sử dụng 2 FF. Tại vị trí sel và enable cùng tích cực mức 1, tương ứng với việc sync_sel và sync_en cùng tích cực mức 1 thì dữ liệu sẽ data_in[7:0] sẽ được ghi vào thanh ghi data_reg[7:0]. Đấy là mong muốn của người thiết kế khi thực hiện mạch trên. Tuy nhiên việc đồng bộ như vậy là không đủ để mạch hoạt động chính xác cho dù độ rộng các tín hiệu sel, enable và data đã được đảm bảo như đã trình bày ở mục 1. Ví dụ như trong hình minh họa sau đây, do độ trễ giữa các tín hiệu  khác nhau nên sel vi phạm định thời trước, enable vi phạm định thời sau. Sau trạng thái bất ổn định, giá trị logic ở pre_sel và pre_en có thể đều về "0" làm cho sync_sel và sync_en không cùng một thời điểm như mong muốn và tín hiệu load không được tích cực.
Hình 9. Do độ trễ giữa các tín hiệu khác nhau nên dữ liệu không được nhận ở miền clk_b
Nếu vẫn muốn sử dụng cách đồng bộ này, giải pháp là phải lái hai tín hiệu điều khiển theo một giao thức ràng buộc về mặt định thời sao cho bất cứ vi phạm timing nào xảy ra thì miền xung clock nhận vẫn lấy được dữ liệu đúng. Ví dụ, tín hiệu enable không cùng chuyển trạng thái logic với tín hiệu sel như hình sau đây.
Hình 10. Tạo một giao thức ràng buộc giữa tín hiệu sel và enable
Một giải pháp khác là biến đổi hai hoặc nhiều tín hiệu điều khiển về một tín hiệu nếu có thể trước khi đồng bộ. Ví dụ như hình sau, sel và enable được xử lý AND ở miền xung clock clk_a trước thành tín hiệu load trước khi được đồng bộ qua miền xung clock clk_b. Dù xảy ra vi phạm thì miền clk_b vẫn nhận đúng dữ liệu khi data_in[7:0] được duy trì độ rộng phù hợp. Độ rộng của data_in[7:0] là:

Tdata > 3*Tclk_b + tsu + th
Hình 11. Biến đổi về đồng bộ 1 tín hiệu
2.2 Đồng bộ hai tín hiệu hoạt động tuần tự

Hai tín hiệu điều khiển được tích cực tuần tự trước sau. Tín hiệu load chỉ tích cực khi tín hiệu en1 tích cực trước và ngay sau đó, en2 tích cực. Tuy nhiên, việc sử dụng mạch đồng bộ 2 FF cho từng tín hiệu en1 và en2 cho kết quả không mong muốn khi trạng thái bất ổn định xảy ra như hình sau. Trường hợp này giả sử các tín hiệu ổn định về "0" sau trạng thái bất ổn định.
Hình 12. Hai tín hiệu tuần tự được đồng bộ không đúng
Giải pháp đầu tiên là chuyển về 1 tín hiệu, xử lý tổ hợp tín hiệu ở miền xung clock clk_a trước khi đưa qua miền clk_b như hình sau.
Hình 13. Xử lý 2 tín hiệu hoạt động tuần tự trước khi đồng bộ
Nếu không thể tổ hợp được hai tín hiệu en1 và en2 thành một tín hiệu nhưng en1 và en2 luôn hoạt động tuần tự trước sau như đã mô tả thì chỉ cần đồng bộ một tín hiệu en1 và dịch tín hiệu sau đồng bộ thêm 1 xung clock ở miền clk_b để tạo ra tín hiệu sync_en2 như minh họa dưới đây.
Hình 14. Tạo tín hiệu phù hợp sử dụng phương pháp dịch

2.3 Đồng bộ các tín hiệu được sử dụng cho encoder, MUX hoặc DEMUX

Giả sử một bộ MUX ở miền clock clk_b sử dụng 2 hoặc nhiều tín hiệu điều khiển từ miền clock clk_a. Nếu chỉ đồng bộ tất cả các tín hiệu bằng FF thì encoder không đảm bảo được hoạt động chính xác vì các tín hiệu điều khiển có thể xuất hiện các tổ hợp giá trị không mong muốn. Nguyên nhân là do độ trễ khác nhau trên các tín hiệu hoặc sự xuất hiện của trạng thái bất ổn định.
Hình 15. Ngõ ra bộ MUX xuất hiện giá trị sai khi đồng bộ song song 2 tín hiệu điều khiển
Một giải pháp cho vấn đề này là tạo thêm một tín hiệu cho phép. Tín hiệu này tích cực sau một chu kỳ xung clock clk_b khi sel1 và sel2 chuyển sang giá trị mới và thôi tích cực trước 1 chu kỳ khi sel1 và sel2 chuyển sang giá trị tiếp theo.

Hình 16. Sử dụng tín hiệu cho phép để lấy được giá trị điều khiển chính xác từ sel1 và sel2
Trên đây là một số trường hợp đồng bộ tín hiệu điều khiển giữa hai miền clock bất đồng bộ.

** Nếu có ý kiến cần trao đổi, bạn có thể comment dưới bài viết để cùng nhau hoàn thiện thêm kiến thức.

Lịch sử cập nhật:
2020.01.07 - Sửa link hình ảnh

8 bình luận:

  1. Bài này bị mất hình rồi anh Quân ơi

    Trả lờiXóa
  2. Bài này bị mất hình rồi anh Quân ơi

    Trả lờiXóa
  3. anh có sử dụng phần mềm ads để thiết kế không ạ, em muốn hỏi về trình giả lập ptolemy trong thiết kế số ads

    Trả lờiXóa
  4. anh có sử dụng phần mềm ads để thiết kế không ạ, em muốn hỏi về trình giả lập ptolemy trong thiết kế số ads

    Trả lờiXóa
    Trả lời
    1. Hi Phuong,
      anh không dùng phần mềm ADS, nó là advanced design system của Agilent đúng ko? Cái này chuyên dụng cho thiết kế analog, RF?
      Nhóm anh hiện chủ yếu là bên digital (coding và verification)

      Xóa
  5. Theo như mình thấy thì khi sử dụng các DFF nối tiếp nhau thì khoảng cách dây nối giữa các dây dẫn càng nhỏ càng tốt. Nhưng trong FPGA có rất nhiều DFF phân bố trên toàn bộ FPGA. Vậy có cách nào cấu hình để khi load chương trình xuống FPGA thì các DFF này ở gần nhau được không. Mình xin cám ơn.

    Trả lờiXóa
  6. Vì các DFF nối tiếp càng gần nhau càng tốt để hạn chế delay trên dây dẫn. Nhưng DFF trên FPGA có rất nhiều và phân bố trên FPGA. Vậy có cách nào tác động để khi nạp chương trình lên FPGA thì nó ở những vị trí mình mong muốn không. Nếu có cho mình chỉ dẫn càng chi tiết càng tốt. mình cám ơn.

    Trả lờiXóa
    Trả lời
    1. Chào em, anh không chuyên về FPGA và cũng chưa làm cụ thể như câu trả lời là có thể.
      https://www.xilinx.com/support/documentation/sw_manuals/xilinx11/pp_p_process_manually_place_route.htm

      Về chi tiết, chắc em phải tự mò thôi :)

      Xóa