Example #1
0
        private void Send()
        {
            // Reset until they are needed
            controlB.Enabled = false;

            ////////////// BUFFER code
            // if we are receiving stuff from the memory, save it to the buffer
            if (memory_receiving)
            {
                int  buffer = buffer_calc.SaveData();
                byte data   = readResultB.Data;
                tempSendRingBuffer.data     = data;
                tempSendRingBuffer.length   = buffer_calc.MetadataCurrentSaveSegment().accum_len;
                tempSendRingBuffer.socket   = buffer_calc.MetadataCurrentSaveSegment().socket;
                tempSendRingBuffer.sequence = (int)buffer_calc.MetadataCurrentSaveSegment().sequence;
                send_buffer[buffer]         = tempSendRingBuffer;
                Logging.log.Trace($"Got memory. goes to buffer:{buffer} data:0x{data:X2}");
                buffer_calc.FinishFillingCurrentSaveSegment();
                memory_receiving = false;
            }

            // If the last clock had an request, we know that the next clock has
            // to be receiving stuff.
            if (memory_requested)
            {
                memory_receiving = true;
                memory_requested = false;
            }

            // If there are no avaliable next segments, we cannot save data
            if (buffer_calc.NextSegmentReady())
            {
                bool invalid  = false;
                int  addr     = -1;
                int  socket   = -1;
                int  sequence = -1;
                // Get the current focus element, and test if it is ready
                int focused_memory_block = mem_calc.FocusSegment();
                if (mem_calc.IsSegmentDone(focused_memory_block))
                {
                    Logging.log.Trace($"memory segment is not ready, waiting. memory segment: {focused_memory_block}");
                    invalid = true;
                }

                if (!invalid)
                {
                    // Get the socket and the sequence from the current memory block
                    socket   = mem_calc.LoadMetaData(focused_memory_block).socket;
                    sequence = (int)mem_calc.LoadMetaData(focused_memory_block).sequence;
                    int maximum_sequence = sequence_dict.LoadMetaData(socket).maximum_sequence;

                    // Get the first sequence
                    int sequence_pointer = sequence_dict.GetFirstValue(socket);

                    int sequence_memory_block = memory_lookup[sequence_pointer];


                    // If this segment is not the first, push the current segment to top and try again
                    if (sequence_memory_block != focused_memory_block)
                    {
                        Logging.log.Warn("Segment is not the last one");
                        memory_lookup[sequence_dict.Observe(socket, sequence)] = mem_calc.DelaySegment(focused_memory_block);
                        invalid = true;
                    }

                    // If the sequence is bigger than the max, we should not use it, as it is not in order
                    if (sequence > maximum_sequence)
                    {
                        Logging.log.Warn("Segment is in front of sequence, must be missing blocks");
                        memory_lookup[sequence_dict.Observe(socket, sequence)] = mem_calc.DelaySegment(focused_memory_block);
                        invalid = true;
                    }
                }

                // Segment has been tested, and we can now load it's data
                if (invalid)
                {
                    addr = -1;
                }
                else
                {
                    addr = mem_calc.LoadData(focused_memory_block);
                }

                // If we actually can get the address(If buffer empty etc)
                if (addr != -1)
                {
                    Logging.log.Trace($"Requesting memory from addr: {addr} on segment: {focused_memory_block}");
                    // Request the data
                    controlB.Enabled   = true;
                    controlB.IsWriting = false;
                    controlB.Address   = addr;

                    // we now have an request from memory
                    memory_requested = true;

                    // Get the metadata from the memory calculator, subtract the total by one, and
                    // Push it into the segment. This makes it possible to detect the last byte in the loaded data
                    tmp_send_inputdata = mem_calc.LoadMetaData(focused_memory_block);
                    Logging.log.Info($"Decrementing {focused_memory_block} {tmp_send_inputdata.accum_len} done: {mem_calc.IsSegmentDone(focused_memory_block)}");
                    tmp_send_inputdata.accum_len -= 1;
                    mem_calc.SaveMetaData(focused_memory_block, tmp_send_inputdata);

                    // We save the metadata onto the buffer
                    buffer_calc.NextSegment(mem_calc.LoadMetaData(focused_memory_block));
                }
            }

            ///////////// Sending code
            // They are ready, we submit stuff

            Logging.log.Trace($"The load segment valid: {buffer_calc.LoadSegmentReady()} ready: {dataOutBufferConsumerControlBusIn.ready}");


            dataOutBufferProducerControlBusOut.valid = buffer_calc.LoadSegmentReady();

            if (dataOutBufferConsumerControlBusIn.ready)
            {
                send_preload = true;
            }

            // Logging.log.Warn($"ready:{dataOutBufferConsumerControlBusIn.ready} " +
            //                  $"valid:{dataOutBufferProducerControlBusOut.valid} " +
            //                  $"send_preload:{send_preload}");

            if (send_preload && buffer_calc.LoadSegmentReady())
            {
                int addr = buffer_calc.LoadData();

                int socket = send_buffer[addr].socket;
                dataOut.socket = socket;
                byte data = send_buffer[addr].data;
                dataOut.data = data;
                int sequence = send_buffer[addr].sequence;

                dataOutBufferProducerControlBusOut.valid      = true;
                dataOutBufferProducerControlBusOut.bytes_left = (uint)(send_buffer[addr].length);

                buffer_calc.FinishReadingCurrentLoadSegment();

                send_preload = false;

                Logging.log.Trace($"Sending(or preloading valid): " +
                                  $"data: 0x{data:X2} " +
                                  $"buffer_addr: {addr} " +
                                  $"sequence number: {sequence} " +
                                  $"socket: {socket} " +
                                  $"bytes left: {send_buffer[addr].length}");

                // If the segment is fully loaded, we remove it from the sequence dict.
                if (send_buffer[addr].length == 0)
                {
                    Logging.log.Info($"Deleting because all have been sent socket: {socket} sequence: {sequence}");
                    sequence_dict.Delete(socket, sequence);
                }
            }
        }
Example #2
0
        private void Send()
        {
            // Look in the FIFO buffer, and send the next element. If the element is ip segmented,
            // Look through the segments in order, and override the normal fifo order. This way ip segmentation is
            // solved in the buffer. TCP segmentation is solved in the dataout buffer.

            // TODO: If we are at an segment in the ringbuffer where we should submit an segment, but the segment
            // is not done, put it on the top of the FIFO queue, and update the segment pointer, then go to next packet

            // Reset until they are needed
            controlB.Enabled = false;

            ////////////// BUFFER code
            // if we are receiving stuff from the memory, save it to the buffer
            if (memory_receiving)
            {
                int  buffer = buffer_calc.SaveData();
                byte data   = readResultB.Data;
                tempSendRingBuffer.data         = data;
                tempSendRingBuffer.length       = buffer_calc.MetadataCurrentSaveSegment().accum_len;
                tempSendRingBuffer.mem_block_id = buffer_calc.MetadataCurrentSaveSegment().mem_block_id;
                send_buffer[buffer]             = tempSendRingBuffer;
                Logging.log.Trace($"Got memory. goes to buffer:{buffer} data:0x{data:X2}");
                buffer_calc.FinishFillingCurrentSaveSegment();
                memory_receiving = false;
            }

            // If the last clock had an request, we know that the next clock has
            // to be receiving stuff.
            if (memory_requested)
            {
                memory_receiving = true;
                memory_requested = false;
            }

            // If there are no avaliable next segments, we cannot save data
            if (buffer_calc.NextSegmentReady())
            {
                // Get the address for the current focus element
                int focus_segment = mem_calc.FocusSegment();
                Logging.log.Trace($"focus segment: {focus_segment}");
                int addr = mem_calc.LoadData(focus_segment);

                // If we actually can get the address(If buffer empty etc)
                if (addr != -1)
                {
                    Logging.log.Trace($"Requesting memory from addr: {addr} on segment: {focus_segment}");
                    // Request the data
                    controlB.Enabled   = true;
                    controlB.IsWriting = false;
                    controlB.Address   = addr;

                    // we now have an request from memory
                    memory_requested = true;

                    // Get the metadata from the memory calculator, subtract the total by one, and
                    // Push it into the segment. This makes it possible to detect the last byte in the loaded data
                    tmp_send_info              = mem_calc.LoadMetaData(focus_segment);
                    tmp_send_info.accum_len   -= 1;
                    tmp_send_info.mem_block_id = focus_segment;
                    mem_calc.SaveMetaData(focus_segment, tmp_send_info);

                    // We save the metadata onto the buffer
                    buffer_calc.NextSegment(mem_calc.LoadMetaData(focus_segment));
                }
            }

            ///////////// Sending code
            // They are ready, we submit stuff

            Logging.log.Trace($"The load segment status: {buffer_calc.LoadSegmentReady()} ready: {packetOutBufferConsumerControlBusIn.ready}");


            packetOutBufferProducerControlBusOut.valid = buffer_calc.LoadSegmentReady();

            if (packetOutBufferConsumerControlBusIn.ready)
            {
                send_preload = true;
            }

            if (send_preload && buffer_calc.LoadSegmentReady())
            {
                packetOutBus.data_length   = buffer_calc.MetadataCurrentLoadSegment().total_len;
                packetOutBus.ip_dst_addr_0 = buffer_calc.MetadataCurrentLoadSegment().ip_dst_addr_0;
                packetOutBus.ip_dst_addr_1 = buffer_calc.MetadataCurrentLoadSegment().ip_dst_addr_1;
                packetOutBus.ip_src_addr_0 = buffer_calc.MetadataCurrentLoadSegment().ip_src_addr_0;
                packetOutBus.ip_src_addr_1 = buffer_calc.MetadataCurrentLoadSegment().ip_src_addr_1;
                long frame_number = buffer_calc.MetadataCurrentLoadSegment().frame_number;
                packetOutBus.frame_number    = frame_number;
                packetOutBus.fragment_offset = 0;
                uint ip_id = buffer_calc.MetadataCurrentLoadSegment().ip_id;
                packetOutBus.ip_id    = ip_id;
                packetOutBus.protocol = buffer_calc.MetadataCurrentLoadSegment().protocol;
                int  addr = buffer_calc.LoadData();
                byte data = send_buffer[addr].data;
                packetOutBus.data = data;

                packetOutBufferProducerControlBusOut.valid      = true;
                packetOutBufferProducerControlBusOut.bytes_left = send_buffer[addr].length;

                buffer_calc.FinishReadingCurrentLoadSegment();

                send_preload = false;

                Logging.log.Info($"Sending: data: 0x{data:X2} ip_id: 0x{ip_id:X2} buffer_addr: {addr} frame_number: {frame_number} bytes_left: {send_buffer[addr].length}");
            }
        }