Conversation
This imports the LowRISC ariane-ethernet MAC core
This adds compilation and timing fixes to allow building a bitstream
marnovandermaas
left a comment
There was a problem hiding this comment.
This is amazing work. I'll need to test this before I can approve it. In the meantime I've left some minor comments.
There was a problem hiding this comment.
Just from my understanding. If there is a packet that is not accepted, the first 8 bytes of the next RX buffer are written. Then based on that the IP decides whether to drop the packet. Does the nextbuf then stay the same because the packet was rejected? In which case if an accepted packed follows this rejected packet the first 8 bytes will be overwritten again by the accepted packet? Or does the nextbuf get incremented anyway and then the read buffer has this rejected packet inside it?
There was a problem hiding this comment.
The basic idea is that received packet data is always written into next buffer, and the nextbuf pointer is only incremented if this packet is accepted. This means if an accepted packet follows a rejected packet, it will overwrite the rejected packet data in next buffer and only then is the nextbuf pointer incremented.
In reality, the framing top increments nextbuf immediately after the MAC address check for an accepted packet, and with this patch the first 8 bytes of a received packet is always preemptively written into the buffer at (nextbuf+1), then nextbuf is possibly incremented, then the rest of the packet is written into the buffer at the new nextbuf.
This means an accepted packet is fully written at new nextbuf (i.e. old nextbuf + 1), while for a dropped packet, the first 8 bytes is written at (old nextbuf + 1), and the rest is written at old nextbuf, with nextbuf not changing after the fact.
To compensate for this, the software driver reads from (firstbuf+1), then increments firstbuf.
There was a problem hiding this comment.
It's kind of sad that the rest of the data for a dropped packet overwrites the rest of "old nextbuf". This is essentially overwriting the body from the previous valid packet right? Does this not cause any issues when rejected and accepted packets are interleaved?
There was a problem hiding this comment.
Yes it will overwrite the previous valid packet if there is at least 1 valid packet in the buffers. This has not happened in my testing since the packet bandwidth is too low for a packet to arrive before the previous has been completely processed. One way to work around this issue is to enable promiscuous mode and do MAC filtering in the driver.
There was a problem hiding this comment.
I have just reproduced this with interleaved 1500-byte packets, so a workaround is necessary at high bandwidths
There was a problem hiding this comment.
How come you added this as well as the auto-generated version? The RDL version is preferable but we can do that in a later PR. I do feel relatively strongly about that we shouldn't have both the RDL as well as the manually written HAL.
There was a problem hiding this comment.
I didn't use the auto generated header for the driver because I couldn't use a buffer memory width of 64 bits and wasn't sure if the framing top can work with 32-bit accesses. I am happy to spend some time and try moving to the RDL version though.
There was a problem hiding this comment.
I'm happy to keep your manually written file here to move this PR forward. Then we can move to the RDL later once the 64-bit accesses has been fixed.
There was a problem hiding this comment.
Ethernet RDL is now moved to the ethernet_rdl branch. Issue #522 is open regarding the 64-bit memwidth.
This adds the rest of chip AXI crossbar and ethernet MAC to the Genesys2 chip top.
rx_prescale is not reset before use. This causes it to stay as X and the link to later downgrade to 10mbps after reference count overflows.
Without the fix tx_frame_addr counts up when no packet is being transmitted, causing the next packet to have uncontrolled size and content.
The original design assumes the rgmii MAC will report Tx active via mac_gmii_tx_en before the user side axis Tx is finished. This is not the case in simulation, which causes max sized packets to be continuously sent following the intended packet until MAC asserts mac_gmii_tx_en.
Rx logic incorrectly assumed that rx_axis_tlast will be 0 when rx_axis_tvalid is 0. This caused the received packet size to be updated to 1 after the correct size was stored.
tx_axis_tvalid is asserted for an extra 3 cycles after the last transfer, causing data in every packet sent after the 1st packet to be offset by 3 bytes. The fix ensures the tvalid provided to rgmii_soc (tx_axis_tvalid_gated) is 0 when tx_enable_i is 0, which prevents the issue.
Since the MAC needs to check the destination MAC address to decide if the packet should be kept, nextptr indicating the Rx buffer to write into is updated 8 cycles late (6 bytes MAC address + 2 cycles latency). Thus if a packet is accepted, its first 8 bytes will be written into the previous Rx buffer. This patch uses an incremented version of nextptr for the first 8 bytes when writing into the Rx buffer, so that an accepted packet will have the correct data. The caveat is that receiving a packet which is not accepted will overwrite the first 8 bytes of the Rx buffer indicated by the incremented nextptr.
The ethernet MAC updates nextbuf and thus avail at the start of a packet rather than at the end. For large received packets, it is possible for the core to be notified of an available packet and read the packet length before the length is updated, thus incorrectly returning the length of the previous packet in the Rx buffer. This fix ensures avail is only asserted when the entire packet is available.
On reset, the ethernet MAC sets byte_sync and last to 0, which is different from their value after receiving a packet. This causes the first received packet to be lost. This fix ensures byte_sync and last are set to 1 before receiving any packets, allowing the first received packet to be captured correctly.
sync is updated late if the previous packet passes the destination MAC address check, therefore a packet following an accepted packet will always be accepted irrespective of its destination MAC address. This fix ensures sync is updated on time.
This commit adds a hal driver, smoketest and example for ethernet. Address space is also reserved for ethernet in mocha.rdl.
This PR integrates the ariane-ethernet MAC core on a rest of chip AXI crossbar outside Mocha.
RDL,HAL driver, smoketest and example software are also added.Closes #354
Testing the ethernet MAC
Launch wireshark and begin capturing packets on the wired interface, make sure wireshark has sufficient permissions to capture packets.
Once the bitstream is loaded, run the ethernet example:
You should see the following UART output:
Your should also see 10 packets captured in wireshark with the following sizes:
64, 1500, 1500, 1500, 100, 64, 1500, 1500, 1500, 100.To test packet reception, launch python as root, which is necessary to send raw packets.
Then bind to the wired interface with:
You should now be able to send packets to Genesys 2. For example, running the following:
Sends a 1500 byte packet to Genesys 2 with a destination MAC address of
9A:BC:12:34:56:78.You should see the packet length and content reported on the UART output, note that the length and content include the 4-byte FCS.