
Nội dung bài viết này trình bày về lý thuyết tạo và và kiểm tra CRC. Phương pháp thực hiện mạch tính CRC nối tiếp. Đồng thời, bài viết đưa ra một RTL code tính CRC có thể lựa chọn độ dài đa thức sinh (generator polynomial) trước khi tổng hợp và gán giá trị đa thức sinh mong muốn khi sử dụng.
SEMICON cảm ơn tác giả đã có một bài viết chia sẻ rất tuyệt vời giúp cho các bạn đã và chưa hiểu rõ về CRC có cái nhìn tốt hơn và dễ tiếp cận hơn.
1. Tổng quan
Một phương pháp kiểm tra đơn giản đó chính là sử dụng parity bit. Parity bit là phương pháp sử dụng 1 bit để kiểm tra số bit "1" hoặc "0" của chuỗi dữ liệu là "chẵn" hoặc "lẻ". Ví dụ sau đây minh họa việc kiểm tra parity chẵn, tổng số bit 1 trong chuỗi được truyền đi bao gồm cả dữ liệu và bit kiểm tra luôn là một số chẵn.
- Tạo bit parity: XOR tất cả các bit dữ liệu
- Kiểm tra parity: XOR tất cả các bit dữ liệu và bit parity. Nếu giá trị là 1 thì chuỗi dữ liệu nhận bị sai.
- Bit sai có thể là bit dữ liệu hoặc bit parity
- Chỉ phát hiện được nếu số bit sai là số chẵn
CRC (Cyclic Redundancy Code) là một phương pháp phổ biến có độ tin cậy cao hơn nhiều so với sử dụng bi parity. CRC được ứng dụng trong nhiều giao thức có khối lượng dữ liệu truyền lớn hoặc tốc độ truyền dữ liệu cao như CAN, Ethernet, giao tiếp RF 15693, ...
2. Lý thuyết về tính toán CRC
Giá trị chuỗi bit kiểm tra hay chuỗi CRC là số dư của phép chia của chuỗi bit dữ liệu cho một chuỗi bit đa thức sinh (Generator Polynomial). Đa thức sinh là số chia sẽ khác nhau tùy vào mỗi giao thức quy định. Phép chia trong tính toán CRC sử dụng cách tính modulo-2. Modulo-2 thực chất là XOR hai số hạng.
Giả sử đa thức chuỗi dữ liệu cần truyền là M(x):
Đa thức sinh là G(x):
Trong đó:
- am và an bằng 1 hoặc 0
- Độ dài chuỗi CRC bằng độ dài đa thức sinh trừ 1 và bằng số mũ lớn nhất của đa thức sinh và bằng n.
Để tạo CRC, chuỗi dữ liệu cần truyền sẽ được mở rộng thêm n bit về phía bên phải:
Điều này, tương ứng với việc dịch trái n bit chuỗi dữ liệu M(x).
Cuối cùng, chia T(x) cho G(x) và lấy số dư. Số dư chính là chuỗi CRC n bit.
Kiểm tra CRC được thực hiện bằng 1 trong 2 cách sau:
- Lấy chuỗi dữ liệu có cả các bit kiểm tra CRC chia cho đa thức sinh. Nếu số dư khác "0" thì dữ liệu nhận bị lỗi.
- Tách chuỗi dữ liệu và chuỗi CRC riêng. Chỉ lấy chuỗi dữ liệu chia cho đa thức sinh rồi lấy số dư phép chia so sánh với chuỗi CRC. Nếu hai chuỗi khác nhau thì dữ liệu nhận bị lỗi.
x^4 + x + 1 (b10011)
Chuỗi dữ liệu cần truyền có 8 bit như sau:
x^7 + x^5 + x (b1010_0010)
Chuỗi dữ liệu trước khi chia sẽ được mở rộng thêm 4 bit "0":
x^11 + x^9 + x^5 (b1010_0010_0000)
Bộ nhận sẽ không phát hiện được lỗi dữ liệu khi chuỗi dữ liệu bị sai và chuỗi CRC cũng sai trùng với giá trị CRC của chuỗi dữ liệu bị sai. Tuy nhiên, xác suất để xảy ra đúng trường hợp này là thấp. Xác suất này càng thấp khi chuỗi CRC càng dài.
3. Mạch nguyên lý tính CRC
Xem lại các ví dụ đã trình bày trên đây, CRC được tính theo nguyên tắc:
- Nếu bit MSB của lần tính hiện tại bằng 1 thì nó sẽ được XOR (modulo-2) với đa thức sinh
- Nếu bit MSB của lần tính hiện tại bằng 0 thì nó sẽ không đổi
Hình 9. Mạch nguyên lý của CRC-1
Ở hình trên, bit MSB sẽ điều khiển MUX chọn có XOR với đa thức sinh x+1 hay không? Tuy nhiên, sau mỗi chu kỳ tính, bit MSB luôn bị loại bỏ nên mạch MUX và XOR của bit MSB là không cần thiết. Mạch được rút gọn như hình sau:
Biểu diễn thường thấy cho mạch tính CRC như sau:
5.1 Nhận xét
Qua hai ví dụ trên đây, nhận xét chung như sau:
- Tại vị trí mà bit đa thức sinh bằng "0" thì chỉ là phép dịch bit
- Tại vị trí mà bit đa thức sinh bằng "1" thì được chèn cổng XOR
- Dữ liệu nối tiếp để tính CRC dịch từ MSB đến LSB với số lần dịch bằng độ dài dữ liệu cộng độ dài giá trị CRC. Ví dụ, dữ liệu 8 bit dùng CRC-4 thì số lần dịch là 12 lần với 4 bit cuối là 4 bit 0 được thêm vào chuỗi dữ liệu.
Căn cứ vào những nhận xét trên, một thiết kế thực hiện tính CRC tổng quát được thực hiện như sau:
- Sử dụng một define CRC_CTRL_POLY để cho phép tạo tín hiệu input điều khiển giá trị của đa thức sinh nếu muốn. Chú ý, độ rộng tín hiệu điều khiển bằng số bit CRC vằ bằng số mũ lớn nhất của đa thức sinh. Ví dụ, nếu đa thức sinh là x^4 + x + 1 thì độ rộng tín hiệu là 4 bit và giá trị gán cho tín hiệu điều khiển là 4'b0011 (bỏ bit 1 của x^4)
- Sử dụng một define CRC_CHECKER để cho phép tạo chức năng kiểm tra CRC
- Sử dụng một parameter CRC_GPW_MAX cho phép cấu hình độ rộng đa thức sinh. Độ rộng đa thức sinh bằng số mũ lớn nhất của đa thức sinh. Ví dụ, nếu đa thức sinh là x^4 + x + 1 thì CRC_GPW_MAX = 4
- Sử dụng một parameter CRC_POLY_VALUE cho phép gán giá trị đa thức sinh sẽ sử dụng nếu không sử dụng tín hiệu điều khiển được tạo ra bởi định nghĩa CRC_CTRL_POLY. Ví dụ, nếu không định nghĩa CRC_CTRL_POLY, đa thức sinh là x^4 + x + 1 thì CRC_GPW_MAX = 4 và giá trị CRC_POLY_VALUE = 4'b0011
- Nếu chk_en = 0 thì khi ctrl_en = 0, crc_seq sẽ giữ giá trị chuỗi CRC trong 1 chu kỳ xung clock
- Nếu chk_en = 1 thì khi ctrl_en = 0, crc_error sẽ báo lỗi CRC
- crc_error = 1 thì chuỗi kiểm tra bị lỗi CRC
- crc_error = 0 thì chuỗi kiểm tra không bị lỗi
Mạch tổng quát của từng bit trong thanh ghi chứa giá trị CRC như sau:
Link download RTL code và testbench: CRC RTL code
pass (nếu có): nguyenquanicd
5.4 Kết quả mô phỏng
Đa thức sinh: x^4 + x + 1 tương ứng với việc gán ctrl_poly_en = 4'b0011
Dữ liệu dùng để tạo CRC: 1010_0110 sau khi thêm 4 bit "0" là 1010_0110_0000 => Kết quả tính CRC là 1110
Dữ liệu dùng để kiểm tra CRC: 1010_0110_1110. Trong đó, 4 bit LSB 1110 là chuỗi CRC => Kết quả kiểm tra CRC là crc_error = 0
Nguồn: Vimach.net
Mong Muốn Có Thêm Cơ Hội Trong Công Việc
Và Trở Thành Một Người Có Giá Trị Hơn
Bạn Chưa Biết Phương Thức Nào Nhanh Chóng Để Đạt Được Chúng
Hãy Để Chúng Tôi Hỗ Trợ Cho Bạn. SEMICON
Hotline: 0972.800.931 - 0938.838.404 (Mr Long)