コード例 #1
0
    // This method describes the operations required to route the frames
    public static void switch_logic()
    {
        uint i = 0U, ptr = 0U, free = 0U, cnt = 0U;
        var  pkt_size = 0U;
        bool exist = false, doneReading;

        IP       = false;
        metadata = 0UL;
        src_mac  = 0UL;
        dst_mac  = 0UL;
        LUT_hit  = false;

        while (true) // Process packets indefinately
        {
            // Procedure call for receiving the first frame of the packet

            CircularNetworkFunctions.RecvOne(cfb, true, true);

            ep.Parse(cfb);
            mp.Parse(cfb);

            metadata = ep.Metadata;
            dst_mac  = ep.DestMac;
            src_mac  = ep.SrcMac;

            // #############################
            // # Switch Logic -- START
            // #############################
            tmp  = 0UL;
            tmp1 = 0UL;
            tmp2 = 0UL;
            tmp0 = 0UL;
            ptr  = 0U;

            // Search the LUT for the dst_mac and for the src_mac
            for (i = 0U; i < LUT_SIZE; i = i + 1U)
            {
                tmp1 = LUT[i];
                Kiwi.Pause();
                // Get the mac address from LUT
                tmp = tmp1 & 0xffffffffffff0000;
                // Get the output port from LUT
                tmp2 = tmp1 & 0x00000000000000ff;

                // Check if we have a hit in the LUT for the dst_mac
                if (dst_mac == tmp)
                {
                    // Get the engress port numnber from the LUT
                    OQ      = tmp2 << 24;
                    LUT_hit = true;
                    //break;
                }

                // Here we check if we need to update an entry based on the src_mac
                // Get rid off the oq, keep only the mac
                if (src_mac == tmp >> 16)
                {
                    // Update if needed
                    // tmp0    = tmp | (metadata & (ulong)0x00ff0000)>>(byte)16;
                    exist = true;
                    ptr   = i;
                    //break;
                }

                // Save some cycles (maybe)
                if (LUT_hit && exist)
                {
                    break;
                }
            }

            // If we have a LUT hit prepare the appropriate output port in the metadata, otherwise flood
            InterfaceFunctions.SetDestInterface(LUT_hit ? (byte)OQ : (byte)mp.BroadcastInterfaces, cfb);

            // Update entry
            if (exist)
            {
                LUT[ptr] = (src_mac << 16) | ((metadata >> 16) & 0x00ff);
            }
            Kiwi.Pause();
            // Create entry
            if (!LUT_hit)
            {
                LUT[ptr] = (src_mac << 16) | ((metadata >> 16) & 0x00ff);
                free     = free > LUT_SIZE - 1U ? 0U : free = free + 1U;
            }
            // #############################
            // # Switch Logic -- END
            // #############################

            // Send out this frame and the rest
            CircularNetworkFunctions.SendAndCut(cfb);
        }
    }