Show HN: Tự làm card mạng logic rời rạc
(qdiv.dev)Tự làm card mạng logic rời rạc
Bài viết này là một phần của loạt bài về quá trình xây dựng một hệ thống máy tính hoàn chỉnh bằng các mạch logic rời rạc. Đến nay, tác giả đã tạo ra một máy tính có thể chạy các ứng dụng mạng như máy chủ HTTP hoặc game LAN.
Tổng quan
- Năm ngoái, tác giả đã chế tạo một bộ điều hợp lớp vật lý chuyển đổi tín hiệu Ethernet 10BASE-T sang SPI và ngược lại. Khi đó, hoạt động được kiểm thử bằng vi điều khiển STM32, còn giờ đang triển khai mô-đun lớp MAC để kết nối với chiếc máy tính tự chế.
- Cả hai bộ điều hợp đều là song công toàn phần, với phần phát và phần thu độc lập.
Bộ thu
Tóm tắt cách bộ thu hoạt động:
- Dữ liệu SPI nối tiếp được chuyển thành dữ liệu song song theo từng byte, và xung nhịp byte được trích xuất.
- 6 byte đầu tiên được so sánh với chuẩn địa chỉ MAC đích, và các frame không khớp sẽ bị loại bỏ.
- Các byte được ghi vào bộ đệm RAM tĩnh.
- Khi frame kết thúc, bộ thu bị vô hiệu hóa, và các frame tiếp theo sẽ bị từ chối cho đến khi người dùng khởi động lại bộ thu. Bộ đếm byte dừng lại và giá trị của nó được cung cấp cho người dùng.
Thu thập dữ liệu
- Cần chuyển dữ liệu SPI nối tiếp thành luồng byte.
- Dữ liệu nối tiếp được dịch qua thanh ghi dịch (
U32).U30vàU31lần lượt đếm bit và byte. - Tín hiệu ghi RAM tĩnh
recv_buf_weđược tạo bằng D flip-flopU29B. Tín hiệu này xuống thấp trong chốc lát sau mỗi 8 bit của dữ liệu đầu vào. - Các byte nhận được được ghi vào bộ đệm RAM tĩnh 6116 (
U20) dung lượng 2kB. U13,U16,U18tạo thành bộ ghép kênh địa chỉ để chọn một trong hai nguồn cho đầu vào địa chỉ của SRAM (U20): bộ đếm byte hoặc bus địa chỉ hệ thống.- Bộ đệm ba trạng thái
U21chuyển các byte đã nhận vào RAM.
Lọc địa chỉ MAC
- Khi phân tích lưu lượng Ethernet, tác giả nhận thấy các frame thường đến theo những nhóm nhỏ (3-4 frame cách nhau bởi độ trễ ngắn). Các frame trong một nhóm thường có địa chỉ MAC đích khác nhau.
- Điều này dẫn đến suy nghĩ rằng máy tính của mình sẽ không thể lọc frame nhận được theo từng MAC rồi khởi động lại bộ thu đủ nhanh để bắt được frame dành cho nó. Vì vậy cần có cơ chế lọc MAC bằng phần cứng.
- Việc lưu một địa chỉ MAC tùy chỉnh ở đâu đó rồi so sánh với 6 byte nhận đầu tiên là quá phức tạp. Có thể dùng một byte lặp lại (ví dụ
FE:FE:FE:FE:FE:FE) nhưng khá nhàm chán. - Để tạo một chút biến tấu cho địa chỉ MAC của mình, tác giả làm nó thành hàm của chỉ số byte:
- Bit 0 cố định là 0
- Bit 1 cố định là 1
- Bit 2-4 là giá trị đảo của chỉ số byte
- Bit 5-7 cố định là 1
- Với quy tắc này, địa chỉ MAC trở thành
FE:FA:F6:F2:EE:EA. Ngoài ra, để hoạt động với ARP, cũng phải chấp nhận MAC quảng báFF:FF:FF:FF:FF:FF.
Bộ phát
- Tương tự bộ thu, bộ phát không triển khai tạo FCS trong phần cứng mà thực hiện bằng phần mềm.
- Để đơn giản hóa hơn nữa, tác giả quyết định chỉ hỗ trợ frame có độ dài cố định. Cách này giúp tránh phải dùng bộ so sánh số phức tạp, và logic truyền frame chỉ cần dựa vào một bit duy nhất của bộ đếm byte.
- Độ dài frame được chọn là 1024 byte, khá gần với MTU thông thường là 1500 byte.
- Phần tiền tố frame cần cho 10BASE-T (chuỗi
0x55theo sau bởi0xD5) cũng nằm trong 1024 byte và phải được phần mềm nạp vào.
Bộ đếm
- Cũng như bộ thu, hai bộ đếm được dùng để đếm bit (
U12) và byte (U14). - Bộ đếm đầu tiên nhận xung clock 20MHz từ bộ dao động tích hợp.
- 20MHz không được dùng trực tiếp mà ít nhất được chia đôi. Cách này giúp chu kỳ nhiệm vụ của bộ dao động không ảnh hưởng đến tín hiệu đầu ra.
Luồng dữ liệu
- Để chọn đầu vào địa chỉ của RAM (
U22), cùng ba bộ ghép kênh 74HC157 như ở bộ thu được sử dụng (không hiển thị ở đây). U23được dùng để nạp dữ liệu vào RAM.U24đóng vai trò là bộ lưu trữ trung gian cho byte hiện đang được truyền. Ý tưởng ở đây tương tự pipeline VGA của tác giả.- Bộ đếm byte 74HC4040 là bộ đếm ripple và cần thời gian để ổn định, vì vậy
U24cung cấp đầu ra ổn định trong lúc đầu ra RAM vẫn chưa hợp lệ. - Dữ liệu này được đưa vào thanh ghi dịch
U28và dịch ra từng bit.
Giao diện CPU
Từ góc nhìn của lập trình viên, giao diện của bộ điều hợp Ethernet này như sau:
- Cả hai bộ đệm frame đều được ánh xạ tại
0xF000. - Có hai thanh ghi chỉ đọc:
- Thanh ghi trạng thái 8 bit tại
0xFB00có hai cờ:RX_FULL- đã nhận được frameTX_BUSY- đang truyền frame
- Thanh ghi độ dài dữ liệu nhận 16 bit tại
0xFB02
- Thanh ghi trạng thái 8 bit tại
- Ghi bất kỳ giá trị nào vào
0xFB00sẽ khởi động lại bộ thu. - Ghi bất kỳ giá trị nào vào
0xFB01sẽ bắt đầu truyền. - Không có ngắt vì CPU của tác giả không hỗ trợ interrupt.
Lập trình
Tác giả muốn có hỗ trợ mạng nhưng không muốn tự triển khai một TCP/IP stack từ đầu. Đồng thời, trình biên dịch đầu tiên quá tệ và việc lập trình bằng assembly rất phiền, nên cần một trình biên dịch C tử tế. Vì vậy tác giả đã tự viết một trình biên dịch C. Nó đã đủ trưởng thành để biên dịch uIP 1.0 (một thư viện TCP/IP nhỏ). Dù mật độ mã của CPU này rất thấp, uIP vẫn đủ nhỏ để vừa trong RAM và còn chừa chỗ cho các ứng dụng thực tế.
Hiệu năng mạng rất thấp, nhưng xét việc không dùng CPU thương mại hay chip chuyên dụng nào thì tác giả vẫn rất hài lòng:
- Thời gian khứ hồi ping trung bình 85ms
- Tốc độ tải xuống của máy chủ HTTP là 2.6kB/s (phục vụ tệp tĩnh từ thẻ SD)
Kho lưu trữ dự án
Các model, file sơ đồ mạch và bản vẽ PCB có trên GitHub.
Ý kiến của GN⁺
- Dự án này cho thấy sự hiểu biết sâu sắc và niềm đam mê phần cứng của tác giả. Nỗ lực tự triển khai mọi thứ thật sự rất ấn tượng, nhưng về mặt tính thực dụng thì vẫn gây nhiều băn khoăn.
- Các hệ thống máy tính hiện đại rất phức tạp và chuyên biệt, nên việc tự xây dựng mọi thứ từ đầu là cực kỳ kém hiệu quả. Đặc biệt với những lĩnh vực đã được chuẩn hóa và tối ưu hóa tốt như network protocol stack, việc tận dụng các implementation sẵn có sẽ khôn ngoan hơn.
- Dù vậy, những dự án như thế này có giá trị giáo dục rất cao. Chúng cho phép trải nghiệm trực tiếp cách phần cứng và phần mềm cấp thấp tương tác với nhau, cũng như cách các giao thức được triển khai.
- Ngoài ra, trong bối cảnh ngày càng nhiều lập trình viên ngày nay hiểu biết ít hơn về phần cứng, dự án này có thể là một ví dụ quý giá giúp nhắc lại nền tảng của các hệ thống máy tính.
- Điểm đáng tiếc là hiệu năng rất thấp. Nếu muốn tăng tính ứng dụng thực tế thì có lẽ cần một triển khai được tối ưu hơn. Nhưng có vẻ đó không phải mục tiêu chính của dự án này.
1 bình luận
Ý kiến trên Hacker News