Thứ Hai, 26 tháng 8, 2019

[CRC] Bài 2 - Bộ tính CRC nối tiếp với một giá trị khởi tạo

Trong bài 1, đã được viết cách đây rất lâu, tác giả có trình bày ngắn gọn về cách tính CRC (Cyclic Redundancy Code), nguyên lý tính CRC nối tiếp và trình bày một cách thiết kế bộ tính CRC nối tiếp. Bài viết này tiếp tục mô tả một cách thiết kế khác của bộ tính CRC nối tiếp. Các thiết kế này có chút ưu điểm hơn so với cách đã thực hiện ở bài 1. Chuỗi bài viết này được tiếp tục vì có bạn hỏi về CRC làm tác giả chợt nhớ là bỏ bê hơi lâu.
1) Phân tích vấn đề
Vấn đề chính của bộ tính CRC nối tiếp chính là "thời gian tính toán lớn". Thời gian tính toán của bộ tính CRC nối tiếp trình bày ở bài 1 là số chu kỳ xung clock tính bằng số bit chuỗi dữ liệu cần tính cộng số bit chuỗi CRC. Như vậy, nếu chuỗi dữ liệu càng dài và chuỗi CRC càng dài thì số chu kỳ cần để tính được CRC càng nhiều.
Nhược điểm của bộ tính CRC nối tiếp ở bài 1 là việc tính CRC bắt đầu khi thanh ghi dịch CRC, crc_seq[CRC_GPW_MAX-1:0], bằng 0. Khi ctrl_en=1, từng bit dữ liệu mới bắt đầu được dịch vào thanh ghi crc_seq[CRC_GPW_MAX-1:0]. Điều này làm cho việc tính toán mất một số chu kỳ đầu không cần thiết, số chu kỳ này bằng đúng độ dài đa thức sinh, bằng CRC_GPW_MAX là số bit đa thức sinh. Xét lại nguyên tắc tính CRC:
  • 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 1: Minh họa cách tính CRC
Theo nguyên tắc trên, khi bắt đầu tính CRC, thanh ghi dịch crc_seq[CRC_GPW_MAX-1:0] có giá trị 0 nên trong CRC_GPW_MAX chu kỳ đầu tiên, bit MSB luôn bằng 0 và giá trị crc_seq không XOR với giá trị đa thức sinh.
Để giảm số chu kỳ không cần thiết như đã nêu. Khi bắt đầu tính CRC, thanh ghi dịch tính CRC sẽ được nạp ngay các bit cao nhất của chuỗi dữ liệu cần tính. Số bit nạp bằng số bit của thanh ghi dịch và bằng số bit của chuỗi CRC.
2) Mô tả tổng quan thiết kế
Thiết kế này gồm các tín hiệu sau:
  • clk: clock đồng bộ
  • rstN: reset tích cực mức thấp
  • ctrlEn: Enable bộ tính CRC. Tích cực trong 1 chu kỳ để báo có dữ liệu cần tính CRC. Dữ liệu sẽ được đưa vào trên dataIn.
  • dataIn: Dữ liệu cần tính CRC
  • genPoly: Giá trị đa thức sinh sử dụng để tính CRC
  • crcReady: Tích cực mức 1 khi bộ tính CRC rảnh hoặc sau khi tính xong CRC
  • crcSeq: Kết quả chuỗi CRC
Các parameter của thiết kế:
  • CRC_WIDTH: Độ rộng chuỗi CRC
  • DWIDTH: Độ rộng chuỗi dữ liệu cần tính CRC
  • DWIDTH_LSB: Số bit dữ liệu còn lại của chuỗi dữ liệu sau khi trừ đi số bit MSB được nạp vào thanh ghi dịch tính CRC.
  • COUNTERW: Độ rộng bộ đếm số chu kỳ tính CRC
Hình 2: Sơ đồ tín hiệu giao tiếp của bộ tính CRC nối tiếp crcInitialValue
Thiết kế này gồm các mạch logic sau:
  • Một bit trạng thái điều khiển quá trình tính CRC, cho biết khi nào bộ đếm CRC đang hoạt động, calStatus.
  • Một thanh ghi lưu lại giá trị đa thức sinh của mỗi lần tính, genPolyReg.
  • Một thanh ghi lưu lại giá trị các bit thấp của dataIn, dataInReg. Các bit cao sẽ được nạp trực tiếp vào thanh ghi dịch CRC khi bắt đầu tính toán nên không cần thanh ghi để lưu.
  • Một bộ đếm số chu kỳ tính toán CRC, mCounter.
  • Logic tạo ngõ ra crcReady.
  • Thanh ghi dịch tính CRC, crcSeq.
3) Phân tích chi tiết
3.1) Bit trạng thái và logic của crcReady
Bit trạng thái calStatus=1 sau khi ctrlEn=1, nó báo hiệu quá trình tính CRC đang diễn ra. Bit này tự động xóa cùng với bộ đếm chu kỳ tính CRC khi quá trình CRC đã kết thúc, clrmCounter=1.
Hình 3: Logic của bit trạng thái và ngõ ra crcReady
Ngõ ra crcReady=1 khi bộ đếm CRC không hoạt động, tức calStatus=0.
3.2) Thanh ghi lưu giá trị đa thức sinh
Thanh ghi cập nhật giá trị khi ctrlEn=1.
Hình 4: Thanh ghi lưu lại giá trị đa thức sinh
3.3) Thanh ghi lưu các bit LSB của chuỗi dữ liệu
Thanh ghi này lưu lại các bit LSB của chuỗi dữ liệu khi ctrlEn=1. Sau đó, nó sẽ dịch trái 1 bit trên mỗi chu kỳ tính CRC. Bit MSB, dataInReg[DWIDTH_LSB-1], sẽ được nối đến ngõ vào thanh ghi dịch tính CRC.
Hình 5: Thanh ghi lưu lại các bit LSB của chuỗi dữ liệu
3.4) Bộ đếm số chu kỳ tính toán CRC
Bộ đếm tăng 1 đơn vị từ 0 đến DWIDTH-1 trong suốt quá trình tính toán CRC (calStatus=1). Bộ đếm sẽ xóa lại về 0 khi quá trình tính CRC kết thúc. Quá trình tính CRC kết thúc khi số chu kỳ tính toán bằng số bit dữ liệu cần tính.

Hình 6: Bộ đếm chu kỳ tính toán CRC
3.5) Thanh ghi dịch lưu giá trị CRC
Thanh ghi crcSeq vừa là thanh ghi dịch tính CRC vừa là thanh ghi lưu lại giá trị CRC. Khi ctrlEn=1, thanh ghi nạp các bit cao của chuỗi dữ liệu từ dataIn với số bit bằng số bit chuỗi CRC.
Sau đó, thanh ghi bắt đầu quá trình tính toán (calStatus=1), tùy vào bit MSB của thanh ghi, crcSeq[CRC_WIDTH-1], mà giá trị mới của thanh ghi dịch có được XOR với đa thức sinh genPolyReg hay không. Chú ý, giá trị dùng để XOR là giá trị thanh ghi đã được dịch trái 1 bit và kèm với bit MSB của thanh ghi dữ liệu dataInReg.
Hình 7: Thanh ghi CRC
4) Minh họa một kết quả mô phỏng
Trong waveform này, dataIn=16'h0a55 và đa thức sinh genPoly=8'hD5.
Kết quả tính toán được là crcSeq=8'haa khi crcReady=1.
Hình 8: Một waveform mô phỏng tính toán CRC
RTL code cũng được tổng hợp trên phần mềm Quartus II.
Hình 9: Kết quả tổng hợp trên Quartus II
5) Nhận xét
Tuy cách thiết kế này giảm được CRC_WIDTH chu kỳ tính toán nhưng vẫn chưa phải là cách tính CRC nhanh nhất. Một số cách khác sẽ được trình bày trong những bài tiếp theo.

Web tính CRC onlline dùng để kiểm chứng kết quả:

Dữ liệu có thể download:

Lịch sử cập nhật:
1) 2019.08.26 - Tạo lần đầu

0 bình luận:

Đăng nhận xét