Tiếp theo chuỗi bài hướng dẫn tạo RTL code bằng script Perl. Bài này tập trung phân tích cấu trúc chi tiết của ví dụ đã được nêu ở bài 3. Việc phân tích chi tiết này nằm trong bước phân tích cấu trúc lõi IP của phần phân tích TOOL đã trình bày ở bài 1.
1) Phân tích chi tiết khối server
Như đã phân tích ở bài 3, thành phần quan trọng của khối server là các FIFO lưu dữ liệu và địa chỉ. Vì dữ liệu và địa chỉ đi cùng với nhau tạo thành một cặp nên FIFO lưu dữ liệu và FIFO lưu địa chỉ có số ô nhớ (tầng) như nhau. Hai FIFO này sẽ dùng chung còn trỏ đọc và con trỏ ghi. Bên cạnh đó, đây là một thiết kế đồng bộ theo một xung clock nên FIFO sử dụng là loại đồng bộ.
Các bạn hãy tham khảo bài viết về FIFO đồng bộ để hình dung cấu tạo của loại FIFO này. Tác giả sẽ sử dụng RTL code của FIFO đã phân tích trong bài viết FIFO đồng bộ để dùng cho phần này.
Hình 1: Cấu hình FIFO đồng bộ chỉ dùng một clock đồng bộ clk và hai tín hiệu báo trạng thái đầy và rỗng |
RTL code của FIFO sẽ là thành phần không đổi và sẽ là một thư viện của TOOL. Người sử dụng có thể thay đổi dung lượng FIFO, gồm độ rộng bit dữ liệu và số lượng ô nhớ, thông qua TOOL.
Tiếp theo, chúng ta chỉ cần phân tích các tín hiệu sẽ kết nối đến FIFO.
Như đã trình bày chúng ta sẽ có 2 FIFO, một để lưu dữ liệu (D_SFIFO) và một để lưu địa chỉ (A_FIFO). Các tín hiệu điều khiển hai FIFO này là như nhau vì dữ liệu và địa chỉ được truyền từ source theo từng cặp.
sv_ack: tín hiệu ngõ ra báo server sẵn sàng nhận dữ liệu từ source. Chỉ cần FIFO không đầy là server có thể nhận yêu cầu từ source nên sv_ack=1 khi sfifo_full=0.
src_we: tín hiệu ghi FIFO, tích cực mức 1. Nó tích cực khi source yêu cầu truyền dữ liệu, sec_req=1, và FIFO không đầy, sv_ack=1.
abt_re: tín hiệu đọc FIFO, tích cực mức 1. Nó tích cực khi FIFO có dữ liệu (không rỗng), sfifo_empty=0, và arbiter báo đã truyền xong dữ liệu, một trong các bit của abt_ack bằng 1.
Thành phần RTL code cho các mạch điều khiển trên đây là cố định và sẽ nằm trong thư viện RTL của tool. Ở mạch abt_re, số lượng bit của abt_ack thay đổi phụ thuộc vào số lượng destination nên độ rộng bit được gán bằng tham số SEL_WIDTH. Số này sẽ được TOOL tạo ra.
Tiếp theo, chúng ta chỉ cần phân tích các tín hiệu sẽ kết nối đến FIFO.
Hình 2: Kết nối các tín hiệu điều khiển đến FIFO dữ liệu và FIFO địa chỉ |
Hình 3: Mạch nguyên lý tín hiệu ghi FIFO (src_we), đọc FIFO (abt_re) và ngõ ra sv_ack |
src_we: tín hiệu ghi FIFO, tích cực mức 1. Nó tích cực khi source yêu cầu truyền dữ liệu, sec_req=1, và FIFO không đầy, sv_ack=1.
abt_re: tín hiệu đọc FIFO, tích cực mức 1. Nó tích cực khi FIFO có dữ liệu (không rỗng), sfifo_empty=0, và arbiter báo đã truyền xong dữ liệu, một trong các bit của abt_ack bằng 1.
Thành phần RTL code cho các mạch điều khiển trên đây là cố định và sẽ nằm trong thư viện RTL của tool. Ở mạch abt_re, số lượng bit của abt_ack thay đổi phụ thuộc vào số lượng destination nên độ rộng bit được gán bằng tham số SEL_WIDTH. Số này sẽ được TOOL tạo ra.
Một chức năng khác của khối server là giải mã địa chỉ xem gói yêu cầu từ source được gửi đến destination nào. Một bit sv_sel tích cực khi FIFO không rỗng, tức có dữ liệu cần gửi, và địa chỉ destination phải đúng. Ở đây, sv_sel[X] với X = 0, 1, 2, ...., sẽ nối đến arbiter X để gửi dữ liệu cho destination X.
Số lượng mạch trên sẽ thay đổi theo số lượng destination nên RTL code này sẽ được tạo ra bởi TOOL. Tùy vào số lượng destination được cấu hình, số lượng bit sv_sel sẽ được tạo ra tương ứng.
Kết thúc phần phân tích của server, các bạn cần nắm rõ:
Hình 4: Mạch giải mã địa chỉ tạo tín hiệu lựa chọn destination nối đến arbiter |
Kết thúc phần phân tích của server, các bạn cần nắm rõ:
- Trong server, phần nào của RTL code sẽ thay đổi và thay đổi do thông số nào?
- Phần nào của RTL sẽ là thư viện cố định, phần nào sẽ được tạo ra bởi TOOL?
2) Phân tích chi tiết khối arbiter
Mỗi destination được nối đến một arbiter. Nó sẽ phân xử xem gói dữ liệu nào sẽ được truyền đến destination trước. Trên thực tế, khối arbiter thường phải áp dụng thuật toán phù hợp để đảm bảo dữ liệu từ các source đều được gửi đến destination trong một khoảng thời gian thích hợp mà không phải đợi quá lâu như cấp phát quyền ưu tiên luân phiên, round robin, ... Tuy nhiên, để đơn giản, trong ví dụ này, tác giả không thực hiện chức năng đã nói mà chỉ quy định rằng source thứ N-1 luôn ưu tiên hơn source thứ N.
Các bạn hãy xem lại sơ đồ khối của arbiter trong bài 3, khối giải mã dữ liệu (data decoder) sẽ lựa chọn dữ liệu từ các source đưa đến thanh ghi dịch để truyền cho destination.
Đây là một mạch có số lượng bit của tín hiệu sv_sel và số lượng tín hiệu sv_data_* thay đổi tùy vào số lượng source nên sẽ được tạo ra bởi TOOL. Theo mạch nguyên lý này, dữ liệu của source 0 luôn được ưu tiên truyền trước sau đó mới đến source 1, source 2, ...
Tương tự, mạch nguyên lý của khối tạo tín hiệu abt_ack cũng được tạo ra bởi TOOL. Tại một thời điểm, chỉ có một bit trong tín hiệu abt_ack tích cực để báo cho server tương ứng biết gói dữ liệu của nó đã được truyền.
Thành phần cuối cùng của arbiter là thanh ghi dịch để truyền dữ liệu cho destination.
Thanh ghi dịch có các hoạt động sau:
Trước hết, chúng ta xác định xem abt_req sẽ tích cực khi nào để báo cho destination biết có dữ liệu cần truyền? Xem lại waveform bài 3, tín hiệu này tích cực khi dest_ack=0 và arbiter có dữ liệu cần truyền (một trong các bit sv_sel[SEL_WIDTH-1:0] bằng 1. Nó có thể thôi tích cực khi dest_ack=1 và duy trì mức logic này trong suốt quá trình dest_ack=1.
Như vậy, abt_txen có thể tích cực mức 1 khi một trong các bit sv_sel[SEL_WIDTH-1:0] bằng 1 và dest_ack=0. Thời điểm này khối server có dữ liệu đưa cho arbiter nhưng destination chưa đáp ứng việc nhận dữ liệu này.
accepted_req là tín hiệu báo cho khối server biết arbiter đã lấy dữ liệu của nó để truyền. Nó sẽ tích cực mức 1 ngay khi phát hiện abt_req=dest_ack=1 vì lúc này arbiter đã lưu dữ liệu cần truyền trong thanh ghi dịch và destination bắt đầu nhận dữ liệu này.
Cấu trúc của mạch thanh ghi dịch và các tín hiệu điều khiển liên quan là cố định nên nó sẽ là RTL code không cần tạo ra bởi TOOL.
3) Kết luận
Kết thúc bài này chúng ta đã hoàn thành bước phân tích cấu trúc lõi IP trong phần phân tích TOOL. Đồng thời, làm rõ phần nào sẽ thuộc về thư viện TOOL, phần nào cần được tạo ra bởi script của TOOL.
Dựa trên phân tích này chúng ta sẽ phân tích cấu trúc TOOL trong những bài tiếp theo.
Lịch sử cập nhật:
2019.03.16 - Tạo mới lần đầu
2019.03.18 - Cập nhật hình vẽ mô tả arbiter, độ rộng tín hiệu sv_sel và số lượng tín hiệu sv_data_* phụ thuộc vào số lượng source
Mỗi destination được nối đến một arbiter. Nó sẽ phân xử xem gói dữ liệu nào sẽ được truyền đến destination trước. Trên thực tế, khối arbiter thường phải áp dụng thuật toán phù hợp để đảm bảo dữ liệu từ các source đều được gửi đến destination trong một khoảng thời gian thích hợp mà không phải đợi quá lâu như cấp phát quyền ưu tiên luân phiên, round robin, ... Tuy nhiên, để đơn giản, trong ví dụ này, tác giả không thực hiện chức năng đã nói mà chỉ quy định rằng source thứ N-1 luôn ưu tiên hơn source thứ N.
Các bạn hãy xem lại sơ đồ khối của arbiter trong bài 3, khối giải mã dữ liệu (data decoder) sẽ lựa chọn dữ liệu từ các source đưa đến thanh ghi dịch để truyền cho destination.
Hình 5: Mạch nguyên lý của khối giả mã địa chỉ chọn dữ liệu |
Tương tự, mạch nguyên lý của khối tạo tín hiệu abt_ack cũng được tạo ra bởi TOOL. Tại một thời điểm, chỉ có một bit trong tín hiệu abt_ack tích cực để báo cho server tương ứng biết gói dữ liệu của nó đã được truyền.
Hình 6: Mạch nguyên lý của khối tạo tín hiệu abt_ack |
Hình 7: Thanh ghi dịch dùng để truyền dữ liệu nối tiếp |
- Nạp dữ liệu cần truyền khi abt_txen=1
- Dịch dữ liệu nối tiếp khi abt_shiften=1, điều này tương ứng với dest_ack=1, xem waveform bài 3.
Hình 8: Mạch tạo tín hiệu điều khiển thanh ghi dịch |
Như vậy, abt_txen có thể tích cực mức 1 khi một trong các bit sv_sel[SEL_WIDTH-1:0] bằng 1 và dest_ack=0. Thời điểm này khối server có dữ liệu đưa cho arbiter nhưng destination chưa đáp ứng việc nhận dữ liệu này.
accepted_req là tín hiệu báo cho khối server biết arbiter đã lấy dữ liệu của nó để truyền. Nó sẽ tích cực mức 1 ngay khi phát hiện abt_req=dest_ack=1 vì lúc này arbiter đã lưu dữ liệu cần truyền trong thanh ghi dịch và destination bắt đầu nhận dữ liệu này.
Cấu trúc của mạch thanh ghi dịch và các tín hiệu điều khiển liên quan là cố định nên nó sẽ là RTL code không cần tạo ra bởi TOOL.
3) Kết luận
Kết thúc bài này chúng ta đã hoàn thành bước phân tích cấu trúc lõi IP trong phần phân tích TOOL. Đồng thời, làm rõ phần nào sẽ thuộc về thư viện TOOL, phần nào cần được tạo ra bởi script của TOOL.
Dựa trên phân tích này chúng ta sẽ phân tích cấu trúc TOOL trong những bài tiếp theo.
Lịch sử cập nhật:
2019.03.16 - Tạo mới lần đầu
2019.03.18 - Cập nhật hình vẽ mô tả arbiter, độ rộng tín hiệu sv_sel và số lượng tín hiệu sv_data_* phụ thuộc vào số lượng source
0 bình luận:
Đăng nhận xét