• 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

Chủ Nhật, 30 tháng 12, 2018

[Q&A] Danh sách đề tài dành cho các bạn sinh viên muốn làm đồ án, luận văn, nghiên cứu về vi mạch số

Vì nhiều bạn có email nhờ mình gợi ý một số đề tài để các bạn có thể lựa chọn làm đồ án nên mình tạo ra bài viết này với mục đích gợi ý một số đề tài và hướng nghiên cứu cho các bạn. Đối với mỗi đề tài, mình sẽ mô tả sơ qua nội dung, mục đích và lợi ích mà các bạn sẽ nhận được sau khi thực hiện xong. Bên cạnh đó, mình cũng nêu một số kinh nghiệm để bạn có thể chọn đề tài phù hợp. 

1) Các yếu tố chính cần quan tâm
Chú ý, việc chọn đề tài phù hợp là tùy vào nhiều yếu tố nhưng mình sẽ trình bày trên quan điểm "đề tài là công việc đầu tiên và tiên quyết" chứ không phải là một môn học mà bạn chỉ tập trung cố gắng để qua môn. Khi xem "Đề tài là công việc đầu tiên và tiên quyết", bạn sẽ có thái độ chuyên nghiệp khi làm nó. Bạn sẽ cần có kế hoạch thực hiện cụ thể, mục tiêu? làm gì? bao lâu?, sẽ gặt hái được gì khi làm xong đề tài?, có giúp ích cho cơ hội nghề nghiệp không?. Khi có thái độ đúng, bạn sẽ hành động đúng và việc "qua môn" với kết quả tốt là hiển nhiên. Ngược lại, nếu bạn chỉ tập trung làm sao để qua môn thì bạn sẽ có xu hướng tìm các đề tài "dễ", những đề tài đã có người làm hoàn thiện, có source code sẵn, chỉ chỉnh sửa, đọc hiểu là được.
Lý do bạn gặp khó khăn khi không thể tự nghĩ ra đề tài nghiên cứu tìm hiểu là:
  1. Bạn chưa có đủ thời gian, kiến thức và kinh nghiệm để nghiên cứu, tìm hiểu, và đánh giá đề tài.
  2. Nhà trường ít cung cấp kiến thức về ngành nghề, cập nhật tình hình phát triển, hay truyền đạt các kinh nghiệm công việc thực tế hoặc có truyền đạt nhưng bạn không để ý.
Để lựa chọn được đề tài phù hợp bạn cần có sự đánh giá kỹ lưỡng dựa trên những gì bạn đang có, các yếu tố để đánh giá gồm:
  1. Năng lực hiện tại của bản thân
  2. Mục tiêu nghề nhiệp của bạn khi ra trường
  3. Xu thế tuyển dụng
  4. Học thuật và tính mới
Năng lực hiện tại của bạn thân, đây là yếu tố đầu tiên, quan trọng nhất để chọn đề tài. Để đánh giá được năng lực này, bạn có thể dựa trên kết quả và cảm giác của bạn khi học các môn liên quan đến vi mạch số như vi xử lý, kỹ thuật số, FPGA, thiết kế số, ... Kết quả những môn này tốt, chứng tỏ bạn có khả năng. Bạn thấy "thích" học, dễ hiểu, dễ tiếp thu các môn này, chứng tỏ năng lực bạn tốt. Thời gian bạn đầu tư cho các môn này ít nhưng kết quả đạt được là tốt, chứng tỏ năng lực trên cả tốt. Tuy bạn không cần nhiều thời gian để học các môn này nhưng vẫn dành thời gian tìm hiểu thêm, chứng tỏ năng lực của bạn tốt++. Kết quả của bạn không xuất sắc nhưng bạn vẫn hiểu tốt kiến thức và các môn này không làm bạn lo sợ, bạn chỉ chậm nhưng khả năng có sẵn.
Mục tiêu nghề nghiệp, sau năng lực, tác giả xếp yếu tố này ở vị trí thứ 2. Khả năng của bạn tốt nhưng không có mục tiêu nghề nghiệp đối với ngành "vi mạch số". Bạn mong muốn ra trường làm lĩnh vực khác hoặc đã định hướng rõ ràng sẽ làm lĩnh vực khác. Việc làm đề tài về "vi mạch số" chỉ để có thể nhanh chóng thực hiện, để "qua môn" với kết quả tốt thì bạn có thể lựa chọn đề tài mức "vừa phải.
Xu thế tuyển dụng, xu thế tuyển dụng sẽ ảnh hưởng lớn đến cơ hội nghề nghiệp sau khi ra trường là rộng hay hẹp. Một đề tài đem lại cho bạn kiến thức "hot" mà trị trường tuyển dụng đang săn đón tất nhiên sẽ ngon hơn. Đối với mục này, bạn cố gắng bỏ ra một chút thời gian tìm hiểu trên các trang tuyển dụng, trang web các công ty, các diễn đàn vi mạch điện tử để xem hiện họ đang cần gì? Trừ khi bạn có ý định đi nước ngoài, công việc rất nhiều và loại nào cũng có. Nếu bạn ở Việt Nam, bạn nên xem có những công ty nào, đang làm gì? Nếu bạn không có ý định làm thuê mà sẽ start-up với việc lập một công ty công nghệ thì tuyệt vời, những lời khuyên của tác giả sẽ là dư thừa và không đủ tầm với bạn vì bạn rất bản lĩnh.
Học thuật và tính mới, đây là yếu tố khó có thể bỏ qua khi bạn thực hiện một đề tài hay luận văn trong môi trường học đường vì nó giúp phân biệt đề tài bạn làm với các đề tài đã được làm trước đó. Khi bạn chọn làm đề tài, cố gắng tìm hiểu để trả lời được "đề tài này khác gì so với các đề tài tương tự?" hoặc "đề tài sẽ giúp giải quyết vấn đề gì, khó khăn gì?" trong lĩnh vực bạn nghiên cứu. Đối với một sinh viên, yêu cầu về cái mới hoàn toàn, chưa có ai làm trên thế giới, là vô cùng khó nhưng tối thiểu nên mới hơn so với những đề tài mà các bạn khác đã làm.
2) Đánh giá xu thế nghề nghiệp về lĩnh vực vi mạch
Quá trình điện tử hóa, tự động hóa diễn ra mạnh mẽ với công nghệ đổi mới liên tục và nhanh chóng. Tính cạnh tranh trong lĩnh vực này rất cao, nhiều công ty hàng đầu luôn cập nhật và áp dụng các tiêu chuẩn mới ngay cả khi nó chưa được công bố chính thức để dẫn đầu và định hướng thị trường. Việc một tiêu chuẩn được công bố, các công ty bắt đầu dựa trên đó là làm theo, điều này là bình thường và nhưng quá chậm. Các công ty hàng đầu sẽ tự đánh giá xu thế để làm trước các sản phẩm ngay khi tiêu chuẩn chưa ban hành.
Quá trình điện tử hóa, tự động hóa len lỏi vào tất cả các lĩnh vực, không chỉ mỗi công nghệ thông tin mà vào cả nông nghiệp, giao thông vận tải, quản lý, ... Ví dụ như:
  • Nông nghiệp: điều khiển tưới tiêu, tự động đo đạc thông số môi trường và cảnh báo, ...
  • Giao thông vận tải: giám sát hành trình phương tiện giao thông, giám sát lưu lượng xe trên đường, ...
  • Quản lý: quản lý hàng hóa bằng chip điện tử, quản lý nhân sự bằng thẻ điện tử, ...
Với yêu cầu ngày càng cao, chức năng vi mạch (chip) phải tích hợp ngày càng nhiều làm cho các vi mạch SoC phát triển mạnh nên kiến thức về hệ thống SoC đã trở thành kiến thức được yêu cầu chung trong yêu cầu tuyển dụng.
Trong hệ thống SoC, các thành phần qua trong không thể thiếu (hầu như luôn tồn tại) là CPU, bus hệ thống, bộ nhớ (memory), module cấp clock, module cấp reset, module quản lý năng lượng (cấp nguồn), DMA nên nghiên cứu về các vấn đề này là lợi thế nghề nghiệp. Về đỉnh cao công nghệ, hiện nay, các ngoại vi liên quan đến giao thức tốc độ cao, băng thông lớn như Ethernet, USB, PCI, DRAM, Video/Audio (HDMI, H.264, H.265, ...) đang "hot" nên nghiên cứu về các vấn đề này sẽ cớ cơ hội nghề nghiệp cao.
Bên cạnh đó, trong flow thiết kế vi mạch số. Nhóm công việc liên quan đến Back-end (tổng hợp, synthesis, layout, ...) đang gia tăng ở Việt Nam và hiện là nhu cầu khá cao trên thế giới vì để có được kinh nghiệm trong phân khúc này không hề đơn giản. Nguyên nhân chính là nó phụ thuộc nhiều vào số thời gian làm việc, tiếp xúc trực tiếp với các phần mềm, thư viện chuyên dụng, có bản quyền để tạo ra các kết quả chính xác. Trong khi phần mềm cho front-end có thể dễ dàng tìm kiếm, cài đặt thì phần mềm dành cho back-end rất khó tìm free và đầy đủ để nghiên cứu và tìm hiểu.
Hình 1: Vị trí nghề nghiệp trong lĩnh vực vi mạch số
3) Danh sách đề tài, luận văn
Danh sách đề tài luận văn mà các bạn có thể tham khảo thực hiện (chú ý, danh sách này sẽ được cập nhật liên tục khi tác giả có ý tưởng mới):
TT Tên Nội dung
1 Thiết kế CPU với kiến trúc tập lệnh mở RISC-V RISC-V đọc là "risk-five" là một tập lệnh mở và miễn phí, hiện nay cộng đồng hỗ trợ và phát triển RISC-V rất đông và đã có một số công ty start-up phát triển sản phẩm dựa trên kiến trúc tập lệnh này (https://riscv.org/). Nếu bạn chọn đề tài thiết kế CPU, đây là một gợi ý.
Ưu điểm: mới hơn so với các đề tài hiện có vì các đề tài trước đây chủ yếu làm theo kiến trúc tập lệnh ARM, PIC. Bạn sẽ có kiến thức về CPU, thành phần không thể thiếu trong các chip SoC, MCU, và là kiến thức tối quan trọng trong lĩnh vực vi mạch số
2 Thiết kế CPU đa nhân (multicore) Thiết kế một CPU có 2 core vật lý trở lên. Khác với đề tài thiết kế 1 core, bạn tập trung phát triển 1 CPU hỗ trợ càng nhiều lệnh càng tốt, chạy càng nhanh càng tốt thì đề tài này bạn tập trung đến vấn đề tối ưu xử lý và phối hợp giữa các core. Kiến trúc mỗi core có thể lựa chọn đơn giản vì đây không phải mục tiêu chính.
Ưu điểm, multicore là xu thế công nghệ hiện tại, đây cũng là đề tài mới ở Việt Nam.
3 Thiết kế bộ quản lý và truy xuất bộ nhớ Cache trong CPU Việc xử lý nhanh hay chậm của CPU liên quan mật thiết đến thời gian truy xuất bộ nhớ chương trình và bộ nhớ dữ liệu. Để giảm thời gian này, các CPU hỗ trợ bộ nhớ đệm Cache. Việc quản lý truy xuất bộ nhớ này là một phần quan trọng trong hoạt động CPU. Đối với đề tài này, bạn không thiết kế CPU mà tập trung nghiên cứu và hiện thực có hiệu quả thành phần quản lý và truy xuất Cache. (https://en.wikipedia.org/wiki/CPU_cache)
4 Thiết kế CPU có kiến trúc superscalar Trong khi Pipeline là kiến trúc giúp giảm số chu kỳ xử lý của một lệnh và hướng đến mục tiêu 1 lệnh/1 chu kỳ, đề tài này đã có nhiều bạn thực hiện thì kiến trúc superscalar giúp CPU xử lý hai hoặc nhiều lệnh song song nhau làm tăng hiệu suất đáng kể. (https://en.wikipedia.org/wiki/Superscalar_processor)
5 Thiết kế Java CPU Một CPU có phần cứng hỗ trợ máy ảo Java giúp thực thi code Java nhanh hơn các CPU thông thường. (https://en.wikipedia.org/wiki/Java_processor)
6 Thiết kế hệ thống BUS đa tầng, phân chia truy cập theo khu vực Trong một SoC, nếu chỉ có một BUS gắn nhiều master và slave thì tốc độ xử lý và hiệu suất hệ thống sẽ rất chậm. Nó giống như việc chỉ có một con đường duy nhất dẫn đến nhiều địa điểm khác nhau nên khi nhiều người cùng muốn đi thì tình trạng "kẹt xe" xảy ra. Trong đề tài này, vấn đề chính bạn cần giải quyết là xây dựng mô hình hệ thống BUS đa tầng để phân luồng truy cập cho các master đến các slave. Chú ý, thiết kế chi tiết, viết RTL code cho tuwngf BUS không phải mục tiêu của đề tài. Mục tiêu chính của đề tài này là bạn có một mô hình SoC với các master, slave có tốc độ xử lý, chức năng khác nhau và bận cần xây dựng (build) một hệ thống BUS kết nối chúng sao cho hiệu suất hoạt động của toàn hệ thống trong ứng dụng là tốt nhất. Cái khó là làm sao để chứng minh, đánh giá và so sánh hệ thống của bạn với hệ thống khác.
7 Thiết kế lõi xử lý tín hiệu số DSP Khác với các lõi CPU thông thường, DSP là một loại vi xử lý chuyên dụng hỗ trợ các ứng dụng xử lý tín hiệu số, việc thiết kế lõi DSP yêu cầu 2 vấn đề là phải hỗ trợ tính toán số học và đáp ứng thời gian thực. Vì vậy, ngoài các lệnh cơ bản như một CPU thông thường, DSP còn hỗ trợ nhiều lệnh hỗ trợ tính toán số học như tính toán dấu chấm tĩnh (fixed-point), dấu chấm động (floating-point), MAC (Multiply-And-Accumulate), CONV (Convolution),...
Tham khảo: http://liu.diva-portal.org/smash/get/diva2:281329/FULLTEXT02
8 Thiết kế bus hệ thống WISHBONE Đây là một chuẩn bus mở. Mục đích của nó là thúc đẩy việc tái sử dụng thiết kế bằng cách cố gắng giảm bớt các vấn đề tích hợp hệ thống trên chip. WISHBONE tạo ra một giao diện hợp lý, phổ biến giữa các lõi IP từ đó giúp giảm thời gian phát triển một sản phẩm SoC.
THam khảo: https://opencores.org/howto/wishbone
9 Thiết kế cầu chuyển đổi AXI-to-WISHBONE Thiết kế chuyển đổi giữa giao thức bus AXI (thuộc bộ giao thức AMBA) và giao thức bus WISHBONE. Điểm khó của đề tài này là làm thế nào chuyển đổi hiệu quả, ít ảnh hưởng đến hiệu suất hệ thống bus.
10 Thiết kế các cơ chế đảm bảo chức năng an toàn cho các transaction trong BUS hệ thống Bus hệ thống như AXI, AHB, APB, WISHBONE, OCP, CoreConnect, ... có nhiệm vụ trung chuyển dữ liệu, thông tin giữa các thành phần trong hệ thống. Tuy nhiên, các giao thức BUS không quy định đầy đủ các cơ chế để phát hiện và xử lý tình huống các tình huống lỗi có thể xảy ra khi chip bị ảnh hưởng bởi nhiệt độ, nhiễu, ... Đối với các ứng dụng yêu cầu mức độ an toàn cao, hệ thống bus phải được thiết kế thêm các chức năng an toàn để phát hiện kịp thời các lỗi khi dữ liệu được vận chuyển trong hệ thống BUS. Từ đó, dữ liệu được truyền từ một master đến một slave thông qua hệ thống bus được đảm bảo chính xác.
Nhiệm vụ đề tài là phân tích các lỗi có thể xảy trong hệ thống BUS, cơ đế để phát hiện các lỗi này, thiết kế các logic cho từng cơ chế và tích hợp vào trong một hệ thống bus. Chú ý, việc thêm cơ chế bảo vệ không làm thay đổi giao thức của chuẩn BUS.
Tham khảo: các dòng chip được chứng nhận Functional Safety (http://www.ti.com/ww/en/functional_safety/safeti/SafeTI-26262.html)

Tham khảo thêm:
1/ Download dễ dàng danh sách hơn 100 báo cáo đề tài, luận án về lĩnh vực thiết kế vi mạch, điện tử của sinh viên các nước:
https://www.electronicshub.org/vlsi-projects-for-engineering-students/

2/ Danh sách tên gợi ý các đề tài, bài tập lớn thực hiện với ngôn ngữ mô tả phần cứng trên FPGA:
http://www.siliconmentor.com/fpga-design-and-verilog-hdl-projects-list/
http://technofist.com/VLSI-Projects.html

3/ Download bài báo, đề tài, luận án đã được hoàn thành và công bố của khoa công nghệ và điện tử trường đại học Toronto (Chú ý, tập tin luận án định dạng ".ps" - PostScript, bạn cần download phần mềm chuyên dụng để xem hoặc chuyển đồi file này thành file .pdf):
http://www.eecg.toronto.edu/~pc/research/fullpublist/

Còn tiếp tục cập nhật ...

Nếu bạn có gợi ý hay góp ý, vui lòng comment dưới bài viết hoặc email về nguyenquan.icd@gmail.com

Thứ Sáu, 28 tháng 12, 2018

[System Verilog] Sự khác nhau của mô tả module trong System Verilog và Verilog

Vì mục đích sử dụng của hai ngôn ngữ khác nhau, Verilog chuyên hỗ trợ mô tả thiết kế phần cứng trong khi System Verilog được mở rộng hơn để hỗ trợ mạnh cho việc mô hình hóa phục vụ mô phỏng, nên nhiều quy định có sự khác biệt. Bài viết này phân tích sự khác nhau trong việc mô tả module của ngôn ngữ System Verilog và Verilog.

1) Mở đầu
Một module là thành phần được mô tả bằng một cặp từ khóa module-endmodule. Một module có thể xem như một khối (block) chức năng riêng và phân biệt với các khối chức năng khác. Định nghĩa module được sử dụng để phân chia cấu trúc và cấp bậc trong một thiết kế hoặc môi trường mô phỏng. Điều này giúp việc quản lý các chức năng của thiết kế dễ dàng hơn.
Hình 1. Một thiết kế có cấu trúc phân cấp (hierarchical structure)
Hình 1 minh họa một thiết kế có cấu trúc phân cấp. Chúng ta sẽ sử dụng định nghĩa module-endmodule để mô tả RTL code cho từng cấp trong thiết kế. Cụ thể, chúng ta sẽ có các module sau:
  1. Mức 1: module SOC
    1. Mức 2: module sys
      1. Mức 3: module clock_generator
      2. Mức 3: module reset_generator
      3. Mức 3: module power_management
    2. Mức 2: module core
      1. Mức 3: module CPU
      2. Mức 3: module sys_bus
        1. Mức 4: module bus_1
        2. Mức 4: module bus_2
        3. Mức 4: module bus_3
      3. Mức 3: module USB
      4. Mức 3: module video
      5. Mức 3: module UART
      6. Mức 3: module CAN
Mục đích sử dụng định nghĩa module của System Verilog và Verilog tuy giống nhau nhưng giới hạn về cách thức sử dụng thì có sự khác biệt.
2) Cấu trúc thứ bậc trong Verilog
Đối với Verilog, để tạo ra một thiết kế có cấu trúc có cấp bậc (hierarchy) như trên thì chúng ta cần thực hiện 2 bước sau:
1. Mô tả các module độc lập và không được lồng vào nhau. Chú ý, đối với Verilog không được phép định nghĩa module này lồng trong module kia, nghĩa là một cặp từ khóa module-endmodule không được phép chứa bất kỳ một cặp từ khóa module-endmodule nào khác. RTL code của các module được mô tả độc lập có thể chứa trong 1 file hoặc nằm trong các file khác nhau.

Hình 2: Verilog - Không được mô tả các module lồng vào nhau (trái) mà phải mô tả RTL của các module độc lập (phải)
Hình 3: RTL code của các module có thể đặt trong các file riêng biệt (trái) hoặc trong cùng một file (phải)
2. Gọi module khác bên trong nó bằng cách instantiating. Khi một module được gọi trong một module khác, nó sẽ tạo ra một instance. Một module có thể gọi nhiều module khác nhau hoặc gọi một module nhiều lần để tạo ra nhiều instance khác nhau. Các instance kết nối với nhau và với các thành phần khác trong module gọi nó thông qua các liên kết input, output hoặc port hay chiều (inout).

Hình 4: Verilog - Gọi một module trong một module khác bằng cách tạo instance
Hình 5: Verilog - module bus được gọi 3 lần để tạo ra 3 instance trong module sys_bus
3) Cấu trúc thứ bậc trong System Verilog
Đối với System Verilog, ngoài khả năng cho phép gọi module như Verilog thì nó còn cho phép các khai báo module lồng nhau (nested module). Nghĩa là một cặp từ khóa module-endmodule có thể được khai báo bên trong một cặp từ khóa module-endmodule khác. Tuy nhiên, việc khai báo lồng nhau này chỉ sử dụng trong các thiết kế mô phỏng, mô mình mô phỏng và không sử dụng để mô tả RTL code của thiết kế khả tổng hợp. Để tạo cấu trúc thứ bậc cho một thiết kế khả tổng hợp, chúng ta chỉ sử dụng phương pháp instance như đã trình bày trên đây.
Việc khai báo các module lồng nhau giúp:
1. Phân chia các phần logic khác nhau trong một module mà không cần sử dụng port (không cần khai báo port).
2. Tạo thư viện module cục bộ chỉ sử dụng cho một phần nhất định trong một thiết kế.

Để minh họa việc cách sử dụng khai báo module lồng nhau trong System Verilog, chúng ta xét mô hình D-FlipFlop như sau:

  • ck: là tín hiệu clock của DFF
  • pr: là tín hiệu dùng để thiết lập ngõ ra q bằng 1. Tích cực mức 0.
  • clr: là tín hiệu dùng để thiết lập ngõ ra q bằng 0.Tích cực mức 0.
  • d: là chân dữ liệu đầu vào
  • q: là chân dữ liệu đầu ra
  • nq: là chân dữ liệu thể hiện giá trị bù của q
Hình 6: Mô hình D-FlipFlop
Để mô tả mô hình trên, chúng ta có thể tạo một module tên dff_model sử dụng mô hình cổng nand được System Verilog hỗ trợ sẵn như sau: 
module dff_model (input d, ck, pr, clr, output q, nq);
 wire q1, nq1, q2, nq2;
 nand n1a (nq1, d, clr, q1);
 nand n1b (q1, ck, nq2, nq1);
 nand n2a (nq2, ck, clr, q2);
 nand n2b (q2, nq1, pr, nq2);
 nand n3b (q, nq2, clr, nq);
 nand n3a (nq, q1, pr, q);
endmodule
Mô hình cổng nand được sử dụng trong đoạn code trên là NAND có 3 ngõ vào, 1 ngõ ra. Nếu muốn phân chia các thành phần logic nand thành từng cụm riêng, mỗi cụm có có cấu trúc như 1 RS latch, chúng ta sẽ sử dụng khai báo module như sau:
module dff_model (input d, ck, pr, clr, output q, nq);
  wire q1, nq1, nq2;
  module latch1;
    nand n1a (nq1, d, clr, q1);
    nand n1b (q1, ck, nq2, nq1);
  endmodule
  latch1 i1();
  module latch2;
    wire q2; // only be an internal signal of latch2
    nand n2a (nq2, ck, clr, q2);
    nand n2b (q2, nq1, pr, nq2);
  endmodule
  latch2 i2();

  module latch3;
    nand n3b (q, nq2, clr, nq);
    nand n3a (nq, q1, pr, q);
  endmodule
  latch3 i3();
endmodule
Hình 7: Mô hình DFF với 3 cấu trúc Latch
Với cách mô tả như trên, chúng ta tạo ra một module có cấu trúc cấp bậc với dff_model là top module và bên trong chưa 3 instance là i1, i2 và i3.
Hình 8: Cấu trúc cấp bậc của ví dụ hình 7
Những điểm cần lưu ý trong đoạn code cho ví dụ hình 7:
1. Không khai báo port cho các module con latch1, latch2 và latch3
2. Việc khai báo các biến (trong ví dụ này các biến được khai báo bằng từ khóa input, output wire) trong module dff_model và trùng tên với các tín hiệu dùng trong module latch1, latch2 và latch3 sẽ tạo ra các kết nối từ các module con latch1, latch2 và latch3 đến module dff_module. 
3. Một khai báo biến bên trong module con, ví dụ như q2 của module latch2, chỉ có tác dụng trong phạm vi của module con, và không tạo kết nối đến bên ngoài.
Trong ví dụ trên đây, sau khi latch1, latch2 và latch3 được khai báo, chúng được gọi để tạo ra 3 instance i1, i2 và i3. Trong trường hợp này, mỗi module con chỉ được gọi 1 lần để sử dụng trong module dff_model nên có thể bỏ các dòng code gọi module. Lúc này, các module con không khai báo port sẽ được ngầm hiểu là 1 instance.
module dff_model (input d, ck, pr, clr, output q, nq);
  wire q1, nq1, nq2;
  module latch1;
    nand n1a (nq1, d, clr, q1);
    nand n1b (q1, ck, nq2, nq1);
  endmodule
  module latch2;
    wire q2; // only be an internal signal of latch2    nand n2a (nq2, ck, clr, q2);
    nand n2b (q2, nq1, pr, nq2);
  endmodule

  module latch3;
    nand n3b (q, nq2, clr, nq);
    nand n3a (nq, q1, pr, q);
  endmodule
endmodule
Hình 9: Cấu trúc cấp bậc khi không có dòng code gọi instance đối với các module con không có khai báo port
Chú ý, một module con chỉ được ngầm hiểu là 1 instance khi đó là một module "KHÔNG CÓ KHAI BÁO PORT". Nếu các module latch1, latch2 và latch3 có mô tả đầy đủ các port input, output như một module thông thường thì phải có dòng code gọi module để tạo instance.
Việc khai báo một module con với đầy đủ các khai báo port input, output, inout được sử dụng khi module con này được gọi nhiều lần trong top module.
module part1(....);
  module and2 (input a, b, output z);
  ....
  endmodule
  module or2 (input a, b, output z);
  ....
  endmodule
  ....
  and2 u1(....), u2(....), u3(....);
  or2 y1(...);
  or2 y2(...);
  .....
endmodule
Trong ví dụ trên, hai module con là and2 và or2 được gọi nhiều lần để tạo ra nhiều instance khác nhau trong module part1. Mỗi instance này phải được mô tả các port kết nối như cách gọi module đã trình bày trong phần "2) Cấu trúc thứ bậc trong Verilog" của bài này. Việc khai báo module lồng nhau như trên giúp tạo thư viện module cục bộ chỉ sử dụng cho một phần nhất định trong một thiết kế.
Đến đây, bạn có thể thắc mắc "Tại sao cần phải khai báo module and2 và or2 trong module part1 mà không khai báo bên ngoài?". Việc khai báo hai module and2 và or2 ngoài module part1 và gọi chúng bằng cách instance là hoàn toàn không có vấn đề gì. Bạn vẫn tạo ra được module part1 như mong muốn. Tuy nhiên, việc khai báo bên trong giúp giới hạn phạm vi của module con. Trong trường hợp này, and2 và or2 thuộc phạm vi của module part1 có chức năng X1 và X2. Nhưng trong một module khác, ví dụ như module part2, chúng ta có thể tạo thêm module con cùng tên and2 và or2 có chức năng Y1 và Y2, trong đó chức năng Y1 và Y2 hoàn toàn khác chức năng X1 và X2. Nếu bạn khai báo and2 và or2 bên ngoài module part 1, để tạo thêm module có chức năng Y1 và Y2 thì bạn phải tạo module có tên khác với and2 và or2. 

Tóm lại:
1. Verilog: Không cho phép khai báo module lồng nhau
2. System Verilog: Cho phép khai báo module lồng nhau
3. Nếu mô tả RTL code khả tổng hợp (synthesis) thì phải theo quy định của Verilog
4. Nếu mô tả code để xây dựng các mô hình mô phỏng, thư viện mô phỏng thì có thể dùng quy định của Verilog hoặc System Verilog
5. Sử dụng khai báo module lồng nhau khi cần giới hạn phạm vi sử dụng của module hoặc phân chia các thành phần logic trong một module.

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