QNICE-FPGA icon indicating copy to clipboard operation
QNICE-FPGA copied to clipboard

Add support for Ethernet

Open sy2002 opened this issue 3 years ago • 4 comments

Add support for Ethernet: The first goal is to have an alternative to the serial connection to transfer data between a host computer and the QNICE-FPGA.

The MEGA65 consumer version for example is not having a serial port that is easily available for end users (you can have a JTAG based serial port though). So Ethernet would be really fine here.

sy2002 avatar Aug 29 '20 10:08 sy2002

For V1.7: The "simple" version as Michael described in https://github.com/sy2002/QNICE-FPGA/issues/95#issuecomment-683416030

sy2002 avatar Aug 30 '20 16:08 sy2002

As I already have a working Ethernet solution in a different project, I propose the following "simple" design for the QNICE (based on the other project I made), which can be made ready in just a few calendar weeks.

The Ethernet hardware module will take care of FCS (the 32-bit CRC), and will check the FCS (and strip it away) on the Rx path, and will append a correct FCS on the Tx path.

The frames will contain the 14 byte MAC header, 20 byte IP header, as well as any other headers.

The Ethernet module will not do any additional checksum validation and/or calculation. Nor will it do any MAC address filtering.

Register Map

0 : Rx address 1 : Rx data 2 : Rx control and length 3 : Rx good frames 4 : Rx overflow errors 5 : Rx CRC errors 6 : Reserved 7 : Reserved

8 : Tx address 9 : Tx data A : Tx control and length B : Tx good frames C : Reserved D : Reserved E : Reserved F : Reserved

Buffer access

The Rx and Tx path will operate in similar way, but completely independent of each other.

The register address is an offset into a word-based buffer. The register data is the 16-bit value at the specified offset. In this way the CPU accesses the Ethernet frame one word at a time (little-endian). This means the first byte in the frame is in bits 7-0 and the second byte in the frame is in bits 15-8.

Each buffer is 1k words in size, i.e. 2 kbytes, which is larger than the maximum Ethernet frame size of 1514 bytes.

Buffer control

Each buffer (Rx and Tx) has an associated "ownership" bit. A zero indicates the buffer is owned and controlled by the CPU, while a one indicates the buffer is owned and controlled by the Ethernet module. Ownership can only be given away, not taken.

To receive frames, the CPU must first give ownership to the Ethernet module by setting bit 15 of the Rx control register. When an Ethernet frame is received with errors, the frame data is copied to the Rx buffer, and the Ethernet module sets the length of the frame in the Rx control register and clears bit 15, thereby granting ownership to the CPU. No more frames can be received as long as the CPU has ownership. When the CPU is finished with the frame the CPU again grants ownership to the Ethernet module by setting bit 15.

A similar process happens during transmit. Initially, the Tx path is idle. When the CPU wants to send a frame, the CPU must copy the data to the Tx buffer, write the length to the Tx control register and set bit 15. This grants ownership to the Ethernet module, which transmits the frame. While this is happening, the CPU is not allowed to write to the Tx buffer. When the frame is sent, the Ethernet module automatically clears bit 15, thereby granting ownership back to the CPU.

Possible optimizations

Since the Ethernet works at a rate of 100 Mbit/s, this corresponds to 8 CPU clock cycles per word (assuming 50 MHz CPU clock), and even more when the CPU speed increases.

To increase throughput and avoid the CPU idling, it is possible to insert fast FIFOs (running at the CPU clock speed) inside the Ethernet module. This is not strictly necessary in the first implementation, but can be considered as an option if needed.

Furthermore, it is possible to add interrupt generation, e.g. every time buffer ownership is granted to the CPU. Again, this is not strictly necessary, but can be added later if needed.

Software considerations

On the receive side the software needs to perform MAC address filtering as well as IP address filtering. Furthermore, the software may (should?) perform IP header checksum validation as well as TCP/UDP payload checksum validation.

On the transmit side, the software is required to generate a correct IP header checkum, as well as a correct TCP/UDP payload checksum.

MJoergen avatar Aug 31 '20 08:08 MJoergen

@MJoergen Thank you - this spec sounds very fine! I do not have experience with Ethernet nor with writing an own TCP/IP stack but I guess we can simplify a lot of things for our first use case with is: pure point-to-point data transfer.

@bernd-ulmann I am always getting confused with big/little endian: Is the endian-ness described here "QNICEcy"?

the register data is the 16-bit value at the specified offset. In this way the CPU accesses the Ethernet frame one word at a time (little-endian). This means the first byte in the frame is in bits 7-0 and the second byte in the frame is in bits 15-8.

sy2002 avatar Sep 01 '20 20:09 sy2002

That is a great match for QNICE regarding the endianness (and everything else). :-)

bernd-ulmann avatar Sep 01 '20 20:09 bernd-ulmann