Kiến thức cơ bản

Quy trình thiết kế FPGA

Quy trình thiết kế FPGA

Đây là bài viết sẽ giới thiệu về quy trình thiết kế FPGA.

Như đã giới thiệu ở bài trước, FPGA là quy trình thiết kế Logic được sử dụng rất phổ biến và có phạm vi sử dụng ngày càng được mở rộng. Quy trình thiết kế FPGA vì thế mà cũng được hoàn thiện và có những quy tắc riêng. 

 

Quy trình chung:

1. Thiết kế đặc tả và viết code 

2. RTL verification ( Behavioral Simulation )

3. Synthesis

4. Implementation

5. Kiểm tra trên FPGA board

 

Phần 1: Thiết kế đặc tả và viết code.

Thông thường, trước khi các bạn bắt tay vào viết code, chúng ta cần có một tài liệu miêu tả về các chức năng mà mình phải thiết kế. Tài liệu này là kết quả của quá trình chúng ta làm việc với khách hàng, hoặc nói chung là người đưa ra yêu cầu cho chung ta. Mục đích của việc này là để làm rõ được mong muốn của khách hàng và thể hiện các giải pháp của chúng ta để hiện thực được các yêu cầu đó. 

Ở giai đoạn đầu của quá trình thiết kế đặc tả ( specification ), chúng ta thường chỉ hoàn thành được 70-80% của bản đặc tả cuối cùng. Nguyên nhân là có nhiều ý tưởng thiết kế thường chưa được hợp lý, kèm theo đó, có nhiều vấn đề sẽ nảy sinh khi chúng ta bắt tay vào code và mô phỏng, dẫn đến phải làm lại bản đặc tả cũng như là lựa chọn các phương án thiết kế khác phù hợp hơn. 

Bản đặc tả của thiết kế thường có dạng sơ đồ khối kèm theo các dạng sóng và các diễn tả về chức năng. Ở bước này, yêu cầu người kỹ sư thiết kế phải có trí tưởng tượng cực tốt để có thể hoàn thành tốt bản đặc tả. Bên cạnh đó, khả năng trình bày, vẽ vời và bố trí logic cũng là yếu tố quan trọng mà các bạn cần trao dồi. 

Ví dụ về 1 đặc tả đơn giản:

 

Sau khi có được đặc tả chi tiết cho thiết kế chúng ta sẽ có thể làm được khá nhiều các công việc khác như, tạo test pattern và hoạch định cho quá trình test, và có thể tiến hành coding.

Nếu như chất lượng của phần đặc tả ở mức độ tốt, thời gian dành cho việc coding sẽ giảm. Nếu kỹ sư có kỹ năng code tốt và kinh nghiệm thì hiển nhiên, quá trình code sẽ thuận lợi và tiết kiệm được thời gian. Đối với FPGA, đa số các công cụ đều có tích hợp sẵn tính năng kiểm tra cú pháp cho các bản code. Chính vì thế, sau khi hoàn thiện code, các bạn có thể nạp code vào phần mềm để tham khảo. 

Chi tiết về cách thức, cú pháp và các quy tắc khi viết code sẽ được chia sẻ ở những bài viết khác. 

 

Phần 2: RTL verification ( Behavioral Simulation )

Đây là phần sẽ tốn khá nhiều thời gian đối với bất kỳ thiết kế nào. Về cơ bản, kiểm tra chức năng ( Function verification ) sẽ bao gồm các bước sau: 

2.1 Hoạch định cho việc kiểm tra chức năng ( Verification planning )

Ngay sau khi có được đặc tả của thiết kế, bạn đã có thể tiến hành lên kế hoạch cho quá trình verification. Kết quả của việc lập kế hoạch này là câu trả lời cho các câu hỏi như:  Môi trường test sẽ được xây dựng như thế nào ? Có bao nhiêu chi tiết cần phải kiểm tra ? Thời gian thực hiện việc test này là khoảng bao lâu ? Ai sẽ tiến hành ? Công cụ nào sẽ được dùng đến ? 

Thông thường, ở bước này, chúng ta phải xây dựng được một bảng liệt kê ( checklist ) các điểm phải kiểm tra ( checkpoint hoặc check item ). 

Ví dụ về checklist và các test case ( mẫu thử )

 

2.2 Xây dựng môi trường kiểm tra ( Verification environment ) 

Đa số các thiết kế phần cứng sử dụng ngôn ngữ verilog đều có môi trường kiểm tra được viết bằng chính ngôn ngữ Verilog. Thành phần của một trường test sẽ được nói chi tiết ở một bài viết khác. Các bạn chỉ cần hiểu rằng, môi trường test là nơi dùng để thực thi các chi tiết để kiểm tra tất cả các chức năng của thiết kế. Nơi các bạn có thể xác mình rằng thiết kế của mình đúng hay sai về mặc logic, cũng là nơi hiện thực cho kế hoạch kiểm trả ban đầu. 

Ví dụ về một testbench dùng trong môi trường kiểm tra.

 

Môi trường được tạo ra theo một số nguyên tắc cơ bản. Tuy nhiên, để tạo một môi trường tốt thì cần có những kỹ năng cũng như mức độ kinh nghiệm nhất định. 

Theo sơ đồ khối ở trên, đối tượng được kiểm tra chính là phần DUT ( Design Under Test ). Các khối còn lại thực hiện các chức năng theo như tên gọi.

© Clock Generator: Dùng để tạo ra các tín hiệu xung nhịp theo thiết kế để cung cấp vào bên trong DUT.

© Test pattern supplier: Dùng để tạo các mẫu thử theo như kế hoạch kiểm tra đã được đề ra. 

©  Input initialization: Tạo các tín hiệu đầu vào tại thời điểm ban đầu.

© Output monitor: Thu thập giá trị của các tín hiệu đầu ra.

© Expected value: Đây là phần được tao sẵn từ các mẫu thử. Tùy theo các ý đồ của từng mẫu thử mà ta có các giá trị đầu ra mong muốn tương ứng.

 

2.3 Tạo các mẫu thử ( test pattern )

Để kiểm tra các chi tiết chức năng của thiết kế, chúng ta dựa vào một loạt mẫu thử để áp vào đầu vào của thiết kế. Sau đó, chúng ta thu thập các giá trị đầu ra của thiết kế, đánh giá nó và đưa ra kết luận cũng như nhận xét về phần chức năng đang được kiểm tra. Nếu tất cả các mẫu thử đều cho kết quả như mong muốn, chúng ta có thể kết luận rằng, chức năng của thiết kế đã được đảm bảo. 

Các mẫu thử này thường là một trình tự các hoạt động ở đầu vào của thiết kế, với mong muốn tác động vào một nhóm chức năng nào đó. Những mẫu thử này đều có thể được liệt kê  ngay từ khâu thiết kế đặc tả ban đầu. Chính vì thế, chúng ta nên tiến hành bước hoạch định kiểm tra ngay sau khi có đặc tả, không nhất thiết phải chờ sau khi coding xong. 

2.4 Kiểm tra đầu ra và dạng sóng

Sau khi áp các trình tự hoạt động vào đầu vào, chúng ta có thể thu thập được các giá trị đầu ra từ các output của thiết kế. Việc làm kế tiếp đơn giản là so sánh chúng với các giá trị mong muốn. Nếu phép so sánh này cho kết quả giống nhau, chúng ta sẽ có kết quả Pass cho mẫu thử vừa mới áp dụng. Ngược lại, nếu kết quả là khác nhau, chúng ta sẽ đi đến bước tiếp theo đó là debug

Ví dụ về kết quả của kiểm tra.

 

2.5 Debug

Sau khi có kết quả khác nhau giữa các giá trị mong muốn và giá trị thực tế, chúng ta tiến hành phân tích và tìm ra nguyên nhân. Việc làm này thường được gọi chung là debug. 

Có 2 hướng phân tích chính khi chúng ta có một kết quả "NG" trong bảng kết quả. Thứ nhất đó chính là các đối tượng thuộc là các thành phần đầu vào, cụ thể ở đây là Clock generator, Test pattern supplier và Input initialization. Thứ 2, đó là DUT. Nếu đối tượng thứ nhất có vấn đề, chúng ta cần xem lại cách tạo chúng và sửa chữa để có được đầu vào chính xác. Nếu đối tượng DUT bị vấn đề, thì đấy chính là 1 Bug trong design của chúng ta cần phải tìm ra và sửa lại thiết kế. 

Cũng có nhiều trường hợp, các mẫu thử đi ra ngoài phạm vi chức năng của thiết kế, làm cho mẫu thử đó bị dư thừa, trùng lặp với nhau. Điều này gây tốn thời gian và công sức của người làm bước kiểm tra. Do đó, phải cẩn thận khi làm các công đoạn hoạch định cho quá trình kiểm tra. 

 

2.6 Cập nhật đầu vào và kiểm tra lại

 Sau khi Debug xong, mọi sai sót hoặc thay đổi nào đó cần được cập nhật. Các mẫu thử trước đó cũng cần phải chạy lại để tránh trường hợp ảnh hưởng mà người thiết kế chưa kiểm soát hết được lúc thực hiện cập nhật. 

 

3. Synthesis

Sau khi coding và thực hiện bước verification xong, chúng ta sẽ đi đến bước tiếp theo của quy trình thiết kế, đó là synthesis. Thuật ngữ synthesis được dùng để mô tả về sự chuyển đổi trạng thái của thiết kế ở dạng code sang dạng cổng logic. Quá trình chuyển đổi này sẽ được thực hiện chủ yếu bởi phần mềm thông qua các thông số từ người dùng. Quy trình synthesis được hiểu nôm na theo sơ đồ khối sau đây.

Quy trình Synthesis và các thành phần liên quan.

Đầu vào của quá trình synthesis gồm có 3 phần.

<1> RTL code:

Đây là thành phần tất yếu. Tool sẽ đọc code và phân tích về khả năng synthesis của code đó. Nếu được Tool chấp nhận, code sẽ được synthesis kèm theo các yếu tố khác.  Nếu Tool thông báo rằng code có vấn đề ( Error hoặc Warning ) thì chúng ta cần kiểm tra lại code của mình. 

Ở đây, các bạn sẽ phải chú ý rằng, một thiết kế RTL đã được mô phỏng thành công thì cũng không đảm bảo cho việc synthesis của nó. Synthesis đòi hỏi một số quy định về coding tương đối chặt chẽ hơn so với Verification. 

<2> Lib và Mdl:

Đối với thiết kế Logic, có 2 cách thức thiết kế chính đó là ASIC và FPGA. So sánh về hai quy trình này, các bạn có thể tham khảo tại đây. Đối với FPGA, lib ( library ) và mdl ( model ) thường được đi kèm trong cơ sở dữ liệu của Tool. Người dùng không cần phải cài đặt hay setting gì thêm. Tài nguyên của FPGA là cố định cho mỗi chip mà board mạch hỗ trợ. Do đó, nếu thiết kế từ phần code cần một lượng tài nguyên nhỏ hơn của chip FPGA thì sẽ không thành vấn đề. Ngược lại, nếu phần logic trong thiết kế đòi hỏi sử dụng một lượng tài nguyên lớn hơn trên chip FPGA, thì thiết kế sẽ không thể hiện thực trên chip đó được. Lúc này, người dùng sẽ phải dùng đến một chip FPGA lớn hơn hoặc tối ưu, giảm thiểu các tính năng để dùng được board mạch và chip FPGA hiện có. 

<3> SDC:

Đây là phần khá quan trọng khi nhắc đến quy trình Implemetation nói chung và Synthesis nói riêng. Về cơ bản, đây là dạng dữ liệu của người dùng nhằm cung cấp cho phần mềm những đặc tính về thời gian ( tần số, chu kỳ, độ trễ ) cũng như vật lý ( vị trí đặt, áp và dòng ... ) của thiết kế. Những đặc tính này trở nên quan trọng khi bạn quan tâm đến việc nâng cao tốc độ cho 1 thiết kế có sẵn, hoặc muốn tạo ra một thiết kế với tốc độ và độ phức tạp của logic cao. Nhiều trường hợp, cần thiết phải thay đổi cả thiết kế logic để có thể bảo toàn được tốc độ.

 <4> GATE

Đây là sản phẩm của quá trình synthesis. Nếu các bạn đã quen với công việc của mảng ASIC thì đây là một đối tượng rất quen thuộc trong design flow. Có thể gọi nó là Gate Level Design hoặc Netlist. Ở quy trình ASIC, đối tượng này thường được dùng trong rất nhiều công đoạn bao gồm cả việc mô phỏng chức năng, kiểm tra tính tương đồng về logic, kiểm tra timing v.v. Tuy nhiên, do sự gói gọn của FPGA flow mà đối tượng này rất ít khi được sử dụng, hoặc với sự hạn chế nhất định nào đó. 

 

 <5> Timing, Power, Area

Ngoài Gate Level Design ra, các đặc tính của nó cũng là một phần quan trọng của các dữ liệu đầu ra. Thông thường, bên cạnh yếu tố về mặt chức năng ( functionalities ), khía cạnh kinh tế như diện tích của chip, mức tiêu hao năng lượng và tốc độ của thiết kế cũng là điều mà các kỹ sư rất qua tâm.  Những yếu tố này tốt sẽ giúp cho thiết kế có được lợi thế khi cạnh tranh với các nhà sản xuất khác trên thị trường.

Các phần mềm thiết kế FPGA đều có những phần hỗ trợ để người dùng có thể trích xuất, xem được và phân tích các yếu tố này. Do đó, các bạn sẽ có đủ công cụ để hiểu và nắm được thông số của những thành phần thông tin này. 

 

4. Implementation

Sau khi synthesis, chúng ta đã có một bức tranh toàn cảnh về thiết kế ở 2 mặt, logic và physical.  Phần Implementation này sẽ là lần chi tiết hơn để phần mềm thực hiện các phân tích và tối ưu về mặt physical. Đó là sự sắp đặt các phần tử, sự lựa chọn và kết nối chúng trên một định hướng về sự tối ưu các yếu tố: Timing, Area và Power consumption. 

Cũng tương tự như các công đoạn trước, ở Implementation, phần mềm cũng sẽ cho ra các loại report và log files. Tùy vào các báo cáo đó, nếu có lỗi hoặc cảnh báo xảy ra, người thiết kế có nhiệm vụ phải sửa chữa đầu vào và chạy lại bước này. 

 

5. Kiểm tra trên FPGA board.

Đến bước cuối cùng của quy trình thiết kế FPGA, chúng ta sẽ tiến hành chạy thử ứng dụng và kiểm tra lại chức năng của thiết kế thông qua hoạt động thực tế. Bước này cũng tốn khá nhiều công sức và sự đầu tư, nhất là các thiết kế đòi hỏi có nhiều phần cứng phụ trợ cũng như các loại thiết bị test. Nhiều loại trong số chúng có chi phí rất cao.