Checksum Internet (RFC 1071): bẫy byte có dấu và cộng vòng
Class cần viết: csum · cần máy chấm có SystemVerilog · 6 case (2 mẫu) · giới hạn 4 s/case · ~25 phút
Checksum của header IPv4, TCP và UDP (RFC 1071) là một phép tính nhỏ mà testbench mạng nào cũng cần để sinh gói đúng hoặc kiểm gói của DUT. Trong SystemVerilog, phép tính này có một cái bẫy ngay ở kiểu dữ liệu: byte là số có dấu.
class csum;
static function int unsigned sum8(byte d[$]); // tổng các byte, coi mỗi byte là số KHÔNG DẤU 0…255
static function bit [15:0] inet_csum(byte d[$]); // checksum Internet của chuỗi byte
endclass
inet_csum:
- Ghép từng cặp byte thành từ 16 bit big-endian:
{d[0], d[1]},{d[2], d[3]}… Nếu số byte lẻ thì byte cuối là byte cao của từ cuối, byte thấp bằng 0. - Cộng mọi từ trong số học bù một (one's complement): mọi phần nhớ vượt 16 bit được cộng vòng lại vào bit thấp, lặp cho tới khi vừa 16 bit.
- Kết quả là phần đảo bit của tổng.
Kiểm nhanh: header IPv4 45 00 00 73 00 00 40 00 40 11 00 00 c0 a8 00 01 c0 a8 00 c7 (trường checksum đang là 0) cho checksum 0xB861. Chuỗi rỗng cho 0xFFFF.
Các case
- sum8 với byte nhỏmẫu
- Header IPv4 mẫu → 0xB861mẫu
Cùng 4 case ẩn kiểm các yêu cầu còn lại của đề. Case ẩn chỉ báo đúng/sai, không nói chi tiết: tự tìm chỗ sai từ đề, hoặc mở gợi ý.
Testbench có mô hình tham chiếu riêng, độc lập với lời giải mẫu. Lời giải mẫu đã chạy qua mọi case trên simulator thật, và 4 bản lỗi mẫu đều bị ít nhất một case bắt. Case mẫu sai sẽ cho biết chỗ sai đầu tiên (giá trị mong đợi so với giá trị nhận được); case ẩn chỉ báo đúng/sai.