色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁(yè) > 網(wǎng)絡(luò)與存儲(chǔ) > 設(shè)計(jì)應(yīng)用 > Vivado HLS推動(dòng)協(xié)議處理系統(tǒng)蓬勃發(fā)展(下)

          Vivado HLS推動(dòng)協(xié)議處理系統(tǒng)蓬勃發(fā)展(下)

          作者:KimonKarras JamesHrica 時(shí)間:2015-04-29 來(lái)源:電子產(chǎn)品世界 收藏

            5 流分割和合并

          本文引用地址:http://cafeforensic.com/article/273295.htm

            在協(xié)議處理中,根據(jù)協(xié)議棧特定字段轉(zhuǎn)發(fā)數(shù)據(jù)包給不同模塊,然后在發(fā)送前將不同的流重新組合,是一項(xiàng)關(guān)鍵功能。 HLS允許使用高級(jí)架構(gòu)來(lái)推動(dòng)這一轉(zhuǎn)發(fā)過(guò)程,具體如例4中所示的流合并。

            例4:簡(jiǎn)單的流合并情況

            1 void merge(stream inData[NUM_MERGE_
            STREAMS], stream&outData) {
            2 #pragma HLS INLINE off
            3 #pragma HLS pipeline II=1 enable_flush
            4
            5 static enum mState{M_IDLE = 0, M_STREAM}
            mergeState;
            6 static ap_uint
            rrCtr = 0;
            7 static ap_uint
            streamSource = 0;
            8 axiWord inputWord = {0, 0, 0, 0};
            9
            10 switch(mergeState) {
            11 case M_IDLE:
            12 bool streamEmpty[NUM_MERGE_STREAMS];
            13 #pragma HLS ARRAY_PARTITION variable=stream-
            Empty complete
            14 for (uint8_t i=0;i
            15 streamEmpty[i] = inData[i].empty();
            16 for (uint8_t i=0;i
            17 uint8_t tempCtr = streamSource + 1 + i;
            18 if (tempCtr >= NUM_MERGE_STREAMS)
            19 tempCtr -= NUM_MERGE_STREAMS;
            20 if(!streamEmpty[tempCtr]) {
            21 streamSource = tempCtr;
            22 inputWord = inData[streamSource].
            read();
            23 outData.write(inputWord);
            24 if (inputWord.last == 0)
            25 mergeState = M_STREAM;
            26 break;
            27 }
            28 }
            29 break;
            30 case M_STREAM:
            31 if (!inData[streamSource].empty()) {
            32 inData[streamSource].read(inputWord);
            33 outData.write(inputWord);
            34 if (inputWord.last == 1)
            35 mergeState = M_IDLE;
            36 }
            37 break;
            38 }
            39 }

            本例體現(xiàn)的是模塊合并功能的使用,其中一個(gè)流陣列作為輸入(inData),一個(gè)單流作為輸出(outData)。這個(gè)模塊的功能是以無(wú)區(qū)別的方式從輸入流讀取數(shù)據(jù),然后將讀取的數(shù)據(jù)輸出給輸出流。該模塊采用雙級(jí)FSM實(shí)現(xiàn),其結(jié)構(gòu)與前文介紹的結(jié)構(gòu)一致。

            FSM的第一個(gè)狀態(tài)用于確保選擇輸入流的無(wú)區(qū)別性(fairness)。實(shí)現(xiàn)的方法是使用循環(huán)算法檢查隊(duì)列。該算法在完成上一隊(duì)列的訪問(wèn)之后,即從下一隊(duì)列起查找新的數(shù)據(jù)。第17到19行的代碼采用的即是此循環(huán)算法。常量NUM_MERGE_STREAMS用于設(shè)定待合并的流的數(shù)量。接下來(lái)的第20行負(fù)責(zé)測(cè)試當(dāng)前的流,其內(nèi)容用tempCntr變量標(biāo)示。如果當(dāng)前流非空,則將其設(shè)置為活躍流(第21行)。然后從該流中讀取數(shù)據(jù)(第22行)。如果讀取的數(shù)據(jù)字不是最后一個(gè)數(shù)據(jù)字(由第24行負(fù)責(zé)檢查),則狀態(tài)機(jī)進(jìn)入M_STREAM狀態(tài),然后輸出來(lái)自該流的剩余數(shù)據(jù)字。在處理完成最后一個(gè)數(shù)據(jù)字后,F(xiàn)SM返回M_IDLE狀態(tài),然后重復(fù)上述過(guò)程。

            這個(gè)模塊引入了一個(gè)新的編譯指令,稱為“array_partition”。該編譯指令能讓 HLS了解為了提高吞吐量,是否需要把一個(gè)陣列拆分為多個(gè)子陣列。如果未加設(shè)定, HLS會(huì)使用雙端口B來(lái)訪問(wèn)陣列。如果要在一個(gè)時(shí)鐘周期中訪問(wèn)陣列兩次以上,如果不適當(dāng)?shù)靥岣叱跏蓟g隔(II)的值,該工具將無(wú)法調(diào)度這些訪問(wèn)。在本例中,略去array_partition編譯指令,將NUN_MERGE_STREAMS值設(shè)為8,就可以讓II=4。但因?yàn)橄肽軌蛟诿總€(gè)時(shí)鐘周期內(nèi)訪問(wèn)steamEmpty陣列的所有元素,讓目標(biāo)II=1,我們需要對(duì)這個(gè)陣列進(jìn)行充分分區(qū)。在本例中,該陣列實(shí)現(xiàn)為一組基于觸發(fā)器的寄存器。

            拆分輸入流的過(guò)程耳熟能詳,把來(lái)自一個(gè)流的數(shù)據(jù)字正確地路由到一個(gè)流陣列即可。

            6 抽取字段和重新對(duì)齊字段

            在包處理中,抽取字段和重新對(duì)齊字段是最基本的操作之一。由于數(shù)據(jù)包一般是經(jīng)過(guò)多個(gè)時(shí)鐘周期內(nèi)通過(guò)總線到達(dá)模塊的,常見(jiàn)的情況是需要的字段要么在它們抵達(dá)的數(shù)據(jù)字中未能對(duì)齊,要么分散在多個(gè)數(shù)據(jù)字中(往往兩種情況都有)。因此要處理這些字段,必須將它們從數(shù)據(jù)流中抽取出來(lái),存入緩存然后重新對(duì)齊以便處理。

            例5:源MAC地址抽取示例

            1 if (!inData.empty()) {
            2 inData.read(currWord);
            3 switch(wordCount) {
            4 case 0:
            5 MAC_DST = currWord.data.range(47, 0);
            6 MAC_SRC.range(15, 0) = currWord.data.
            range(63, 48);
            7 break;
            8 case 1:
            9 MAC_SRC.range(47 ,16) = currWord.
            data.range(31, 0);
            10 break;
            11 case 2:
            12 ……

            例5是一個(gè)非常簡(jiǎn)單的字段抽取和再對(duì)齊示例。這個(gè)示例從以太網(wǎng)報(bào)頭中抽取源MAC地址。數(shù)據(jù)通過(guò)稱為“inData”的64位流抵達(dá)。在每個(gè)時(shí)鐘周期讀入數(shù)據(jù)(第2行)。隨后根據(jù)讀取的數(shù)據(jù)字執(zhí)行合適的語(yǔ)句。因此在第5行中源MAC地址的頭16位被抽取出來(lái),并移位到MAC_SRC變量的起始部分。在下一時(shí)鐘周期中,MAC地址的其余32位抵達(dá)總線,然后存入MAC_SRC變量的32位更高位中。

          c++相關(guān)文章:c++教程




          關(guān)鍵詞: Vivado FIFO 存儲(chǔ)器 RAM C/C++

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉