Commit ce156723 authored by Antoine Kaufmann's avatar Antoine Kaufmann
Browse files

add small receive fifo to avoid worst drops

parent d7e300bd
...@@ -627,30 +627,38 @@ class EthernetTx { ...@@ -627,30 +627,38 @@ class EthernetTx {
class EthernetRx { class EthernetRx {
protected: protected:
Vinterface ⊤ Vinterface ⊤
uint8_t packet_buf[2048];
size_t packet_len; static const size_t FIFO_SIZE = 32;
uint8_t fifo_bufs[FIFO_SIZE][2048];
size_t fifo_lens[FIFO_SIZE];
size_t fifo_pos_rd;
size_t fifo_pos_wr;
size_t packet_off; size_t packet_off;
public: public:
EthernetRx(Vinterface &top_) EthernetRx(Vinterface &top_)
: top(top_), packet_len(0), packet_off(0) : top(top_), fifo_pos_rd(0), fifo_pos_wr(0), packet_off(0)
{ {
for (size_t i = 0; i < FIFO_SIZE; i++)
fifo_lens[i] = 0;
} }
void packet_received(const void *data, size_t len) void packet_received(const void *data, size_t len)
{ {
if (packet_len != 0) { if (fifo_lens[fifo_pos_wr] != 0) {
std::cerr << "EthernetRx: dropping packet" << std::endl; std::cerr << "EthernetRx: dropping packet" << std::endl;
return; return;
} }
packet_off = 0; memcpy(fifo_bufs[fifo_pos_wr], data, len);
packet_len = len; fifo_lens[fifo_pos_wr] = len;
memcpy(packet_buf, data, len); fifo_pos_wr = (fifo_pos_wr + 1) % FIFO_SIZE;
#ifdef ETH_DEBUG #ifdef ETH_DEBUG
std::cerr << "EthernetRx: packet len=" << std::hex << packet_len << " "; std::cerr << "EthernetRx: packet len=" << std::hex << len << " ";
for (size_t i = 0; i < packet_len; i++) { for (size_t i = 0; i < len; i++) {
std::cerr << (unsigned) packet_buf[i] << " "; std::cerr << (unsigned) packet_buf[i] << " ";
} }
std::cerr << std::endl; std::cerr << std::endl;
...@@ -659,19 +667,22 @@ class EthernetRx { ...@@ -659,19 +667,22 @@ class EthernetRx {
void step() void step()
{ {
if (packet_len != 0) { if (fifo_lens[fifo_pos_rd] != 0) {
// we have data to send // we have data to send
if (packet_off != 0 && !top.rx_axis_tready) { if (packet_off != 0 && !top.rx_axis_tready) {
// no ready signal, can't advance // no ready signal, can't advance
std::cerr << "eth rx: no ready" << std::endl; std::cerr << "eth rx: no ready" << std::endl;
} else if (packet_off == packet_len) { } else if (packet_off == fifo_lens[fifo_pos_rd]) {
// done with packet // done with packet
#ifdef ETH_DEBUG #ifdef ETH_DEBUG
std::cerr << "EthernetRx: finished packet" << std::endl; std::cerr << "EthernetRx: finished packet" << std::endl;
#endif #endif
top.rx_axis_tvalid = 0; top.rx_axis_tvalid = 0;
top.rx_axis_tlast = 0; top.rx_axis_tlast = 0;
packet_off = packet_len = 0;
packet_off = 0;
fifo_lens[fifo_pos_rd] = 0;
fifo_pos_rd = (fifo_pos_rd + 1) % FIFO_SIZE;
} else { } else {
// put out more packet data // put out more packet data
#ifdef ETH_DEBUG #ifdef ETH_DEBUG
...@@ -680,14 +691,15 @@ class EthernetRx { ...@@ -680,14 +691,15 @@ class EthernetRx {
top.rx_axis_tkeep = 0; top.rx_axis_tkeep = 0;
top.rx_axis_tdata = 0; top.rx_axis_tdata = 0;
size_t i; size_t i;
for (i = 0; i < 8 && packet_off < packet_len; i++) { for (i = 0; i < 8 && packet_off < fifo_lens[fifo_pos_rd]; i++) {
top.rx_axis_tdata |= top.rx_axis_tdata |=
((uint64_t) packet_buf[packet_off]) << (i * 8); ((uint64_t) fifo_bufs[fifo_pos_rd][packet_off]) <<
(i * 8);
top.rx_axis_tkeep |= (1 << i); top.rx_axis_tkeep |= (1 << i);
packet_off++; packet_off++;
} }
top.rx_axis_tvalid = 1; top.rx_axis_tvalid = 1;
top.rx_axis_tlast = (packet_off == packet_len); top.rx_axis_tlast = (packet_off == fifo_lens[fifo_pos_rd]);
} }
//trace->dump(main_time); //trace->dump(main_time);
} else { } else {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment