/* * Function: SendAndCut * Description: Send the entirety of buffer and cut if the whole frame hasn't been sent. */ public static void SendAndCut(CircularFrameBuffer cfb) { var status = 0U; if (cfb.CanPop(true)) { Emu.Interrupts = 1; } else { Emu.Interrupts = 2; } Emu.debug_reg = cfb.Count; while (status <= 1) { status = SendOne(cfb, false, true, false); } if (status == 2) { Reset(); } else if (status == 3) { CutThrough(); } }
/* * Function: SendOne * Description: Send a single segment of the buffered ethernet frame. */ public static uint SendOne(CircularFrameBuffer cfb, bool stop = true, bool movepeek = false, bool checkready = true) { if (cfb.CanPop(movepeek) && (!checkready || Emu.m_axis_tready)) { Emu.Status = 11; SetData(cfb, movepeek, true); var done = cfb.PopData.Tlast; Emu.Status = 3; Kiwi.Pause(); if (stop) { Reset(); } if (done) { Emu.PktOut++; Emu.Status = 12; return(2U); } Emu.Status = 13; return(0U); } Emu.Status = 14; if (stop) { Reset(); } return(3U); }
/* * Function: SendWithFCS * Description: Sends the whole buffered frame, appending the FCS at the end. */ public static bool SendWithFCS(CircularFrameBuffer cfb, crc32 crc) { bool cont = true; crc.Reset(); while (cont) { if (cfb.CanPop(true)) { if (SetData(cfb, true, false, false)) { crc.CRC_Compute(cfb.PopData); cont = !cfb.PopData.Tlast; } ; if (cfb.PopData.Tlast) { var size = (int)NumSize(cfb.PopData.Tkeep); if (size >= 24) { Emu.m_axis_tdata_3 = cfb.PopData.Tdata3 | (crc.CRC_LittleEndian() << ((size % 8) * 8)); } else if (size > 20) { Emu.m_axis_tdata_3 = cfb.PopData.Tdata3 | (crc.CRC_LittleEndian() >> ((24 - size) * 8)); Emu.m_axis_tdata_2 = cfb.PopData.Tdata2 | (crc.CRC_LittleEndian() << ((size % 8) * 8)); } else if (size >= 16) { Emu.m_axis_tdata_2 = cfb.PopData.Tdata2 | (crc.CRC_LittleEndian() >> ((size % 8) * 8)); } else if (size > 12) { Emu.m_axis_tdata_2 = cfb.PopData.Tdata2 | (crc.CRC_LittleEndian() >> ((16 - size) * 8)); Emu.m_axis_tdata_1 = cfb.PopData.Tdata1 | (crc.CRC_LittleEndian() << ((size % 8) * 8)); } else if (size >= 8) { Emu.m_axis_tdata_1 = cfb.PopData.Tdata1 | (crc.CRC_LittleEndian() << ((size % 8) * 8)); } else if (size > 4) { Emu.m_axis_tdata_1 = cfb.PopData.Tdata1 | (crc.CRC_LittleEndian() >> ((8 - size) * 8)); Emu.m_axis_tdata_0 = cfb.PopData.Tdata0 | (crc.CRC_LittleEndian() << (size * 8)); } else { Emu.m_axis_tdata_0 = cfb.PopData.Tdata0 | (crc.CRC_LittleEndian() << (size * 8)); } Emu.PktIn = (uint)size; Emu.m_axis_tkeep = Emu.m_axis_tkeep << 4 | 0xF; //Console.WriteLine($"{size}:{crc.CRC_LittleEndian():X16}"); } Emu.m_axis_tvalid = true; WaitReady(); //System.Console.WriteLine($"{Emu.m_axis_tdata_0:X16},\n{Emu.m_axis_tdata_1:X16},\n{Emu.m_axis_tdata_2:X16},\n{Emu.m_axis_tdata_3:X16}"); //Kiwi.Pause(); } else { Reset(); return(false); } } Reset(); Emu.PktOut++; return(true); }