天天看點

接口綜合參考(Interface Synthesis Reference)

目錄

    • 1 塊級I/O協定
        • ap_ctrl_none
        • ap_ctrl_hs
        • ap_ctrl_chain
    • 2 端口級I/O協定
        • ap_none
        • ap_stable
        • ap_hs (ap_ack, ap_vld, and ap_ovld)
        • ap_ack
        • ap_vld
        • ap_ovld
        • ap_memory, bram
        • ap_fifo
        • ap_bus
        • axis
        • s_axilite
        • m_axi

本部落格解釋了每種Vivado HLS接口協定模式。

1 塊級I/O協定

Vivado HLS使用接口類型ap_ctrl_none,ap_ctrl_hs和ap_ctrl_chain來指定是否使用塊級握手信号實作RTL。塊級握手信号指定以下内容:

  • 當設計的子產品開始執行操作時
  • 當操作完成時
  • 當設計的子產品空且準備好接受新的輸入時

您可以給函數或者函數的傳回值指定這些塊級I/O協定。如果C代碼不傳回一個值,您同樣可以給函數的傳回指定一個塊級I/O協定。如果C代碼使用了一個函數傳回,Vivado HLS會為傳回值建立一個 ap_return 輸出端口。

ap_ctrl_hs 塊級I/O協定是預設使用的協定,下圖展示了Vivado HLS在函數上實作ap_ctrl_hs時産生的RTL端口和行為。在這個例子中,函數利用return文法傳回一個值,因而Vivado HLS在RTL設計建立了一個ap_return輸出端口。如果C代碼中不包含函數的return文法,這一個端口就不會生成。

接口綜合參考(Interface Synthesis Reference)

ap_ctrl_chain 接口模式類似于ap_ctrl_hs,但是提供了附加的輸入信号 ap_continue 來施加反壓。Xilinx建議将Vivado HLS塊連結在一起時使用ap_ctrl_chain塊級I / O協定。

ap_ctrl_none

如果您指定使用 ap_ctrl_none 塊級I/O協定,那麼上圖中的握手信号端口(ap_start,ap_idle,ap_ready 和 ap_done)就不會被建立。如果您沒有在設計中指定塊級I/O協定,那麼您在使用C / RTL協同仿真來驗證RTL設計時,必須遵守 接口綜合要求 中所述的條件。

ap_ctrl_hs

下圖展示了由ap_ctrl_hs I/O協定為非流水線設計而建立的塊級握手(handshake)信号的行為。

接口綜合參考(Interface Synthesis Reference)

複位完成後,将發生以下事件:

① 所設計的塊等待 ap_start 置高電平以開始它的操作

② 輸出 ap_idle 立刻置低電平以訓示此時所設計的塊不再空閑

③ ap_start 信号必須保持高電平直到 ap_ready 置高,一旦 ap_ready 置高:

  • 如果 ap_start 保持高電平,設計的塊将會開始下一次事務
  • 如果 ap_start 置位低電平,設計将完成目前事務并暫停操作

④ 資料可以被輸入端口讀取(注意:輸入端口可以使用獨立于此塊級I / O協定的端口級I / O協定)

⑤ 資料可以被寫到輸出端口(注意:輸出端口可以使用獨立于此塊級I / O協定的端口級I / O協定)

⑥ 當設計的塊完成操作時,輸出 ap_done 置高(注意:如果有ap_return端口,則當ap_done為“高”時,此端口上的資料有效。 是以,ap_done信号還訓示輸出ap_return上的資料何時有效)

⑦ 當設計準備好接受新輸入時,ap_ready 信号變為高電平。 以下是有關ap_ready信号的其他資訊:

  • 在設計開始運作之前,ap_ready信号無效
  • 在非流水線設計中,ap_ready信号與ap_done同時聲明
  • 在流水線設計中,在ap_start被采樣為高電平之後,ap_ready信号可能在任何周期變為高電平,這取決于設計的流水線方式
  • 如果當ap_ready為高電平時ap_start信号為低電平,則設計将執行ap_done為高電平,然後停止操作
  • 如果當ap_ready為高電平時ap_start信号為高電平,則下一個事務處理子立即啟動,并且設計繼續運作

⑧ ap_idle 信号訓示設計何時處于空閑狀态且未運作。 以下是有關ap_idle信号的其他資訊:

  • 如果當ap_ready為高電平時ap_start信号為低電平,則設計停止操作,并且在ap_done之後一個周期ap_idle信号變為高電平
  • 如果當ap_ready為高電平時ap_start信号為高電平,則設計繼續運作,并且ap_idle信号保持低電平

ap_ctrl_chain

ap_ctrl_chain 塊級I/O協定類似于 ap_ctrl_hs 協定,但提供了一個名為 ap_continue 的附加輸入端口。高電平有效的ap_continue信号訓示消耗輸出資料的下遊塊已準備好進行新的資料輸入。如果下遊塊無法使用新的資料輸入,則ap_continue信号為低電平,這将阻止上遊塊生成附加資料。

下遊塊的 ap_ready 端口可以直接驅動 ap_continue 端口。 以下是有關ap_continue端口的其他資訊:

  • 如果當ap_done為高電平時ap_continue信号為高電平,則設計繼續運作。其他塊級I/O信号的行為與ap_ctrl_hs塊級I/O協定中描述的行為相同
  • 如果當ap_done為高電平時ap_continue信号為低電平,則設計停止操作,ap_done信号保持高電平,并且如果存在ap_return端口,則資料在ap_return端口上保持有效。

在下面的圖中,因為當ap_done為高時,ap_continue為高,是以第一個事務完成,并且第二個事務立即啟動。 但是,設計将在第二個事務結束時停止,直到将ap_continue聲明為高為止。

接口綜合參考(Interface Synthesis Reference)

2 端口級I/O協定

ap_none

ap_none端口級I/O協定是最簡單的接口類型,并且沒有其他信号與其關聯。輸入資料信号和輸出資料信号都沒有關聯的用于訓示何時讀取或寫入資料的控制端口。 RTL設計中唯一的端口是源代碼中指定的端口。

ap_none接口不需要其他硬體開銷,盡管如此,ap_none接口需要滿足以下條件:

  • 生産者塊執行以下兩個操作之一
    • 在正确的時間向輸入端口提供資料
    • 保留事務期間的資料,直到設計的塊的操作完成
  • 使用者塊在正确的時間讀取輸出端口

注意:ap_none接口不能與數組參數一起使用。

ap_stable

與ap_none一樣,ap_stable端口級I/O協定不會在設計中添加任何接口控制端口。 ap_stable類型通常用于可更改但在正常操作期間保持穩定的資料,例如提供配置資料的端口。 ap_stable類型将以下内容通知給Vivado HLS:

  • 應用于端口的資料在正常操作期間保持穩定,但不是可以優化的恒定值
  • 此端口的扇出不需要注冊

注意:ap_stable類型隻能應用于輸入端口。 當應用于inout端口時,僅端口的輸入被認為是穩定的。

ap_hs (ap_ack, ap_vld, and ap_ovld)

ap_hs端口級I/O協定在開發過程中提供了最大的靈活性,允許自下而上和自上而下的設計流程。 雙向握手可以安全地執行所有塊内通信,且可以正确操作不需要手動幹預或假設。 ap_hs端口級I/O協定提供以下信号:

  • 資料端口
  • 訓示何時消耗資料的确知信号
  • 訓示何時讀取資料的有效信号

下面的圖顯示了ap_hs接口在輸入和輸出端口上的行為,在此示例中,輸入端口命名為 in,輸出端口命名為 out。

注意:控制信号的名稱是基于原始端口名稱确定的。 例如,用于輸入資料的有效端口名為in_vld。

接口綜合參考(Interface Synthesis Reference)

對于輸入,發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 如果設計已準備好輸入資料,但輸入有效信号in_valid為低,則設計将暫停并等待輸入有效信号in_vld置高以訓示存在新的輸入值(注意:上圖顯示了此行為。 在此示例中,在第4個時鐘周期設計已準備好讀取輸入的資料,并在讀取資料之前停頓等待輸入有效)
  • 當輸入有效信号in_vld置位高電平時,确知信号in_ack就置位高電平,表明已讀取資料

對于輸出,發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 寫入輸出端口時,将同時聲明其關聯的輸出有效信号,以訓示端口上存在有效資料
  • 如果相關的輸入确知信号in_ack為低電平,則設計将停頓并等待輸入确知信号in_ack置高
  • 輸入确知信号in_ack置高後,将在下一個時鐘沿輸出有效out_vld将置為無效

ap_ack

ap_ack端口級I/O協定是ap_hs接口類型的子集,它提供以下信号:

  • 資料端口
  • 确知信号訓示何時消耗資料
    • 對于輸入的參數,設計将生成一個輸出确知端口,該确知信号将在輸入被讀取的周期中為高電平有效
    • 對于輸出的參數,Vivado HLS會實作為一個輸入确知端口,以确認輸出被讀取

注意:在執行寫操作後,設計将暫停并等待直到輸入确認為高電平為止,這表明輸出已由使用者塊讀取。 但是,沒有關聯的輸出端口訓示何時可以使用資料。不能使用C / RTL協同仿真來驗證在輸出端口上使用ap_ack的設計!

ap_vld

ap_vld是ap_hs接口類型的子集。 ap_vld端口級I/O協定提供以下信号:

  • 資料端口
  • 訓示何時讀取資料的有效信号
    • 對于輸入參數,設計将在valid信号有效後立即讀取資料端口。 即使設計尚未準備好讀取新資料,設計也會對資料端口進行采樣并在内部保留所需的資料
    • 對于輸出參數,Vivado HLS實作為一個輸出有效端口,以訓示輸出端口上的資料何時有效。

ap_ovld

ap_ovld是ap_hs接口類型的子集。 ap_ovld端口級I/O協定提供以下信号:

  • 資料端口
  • 訓示何時讀取資料的有效信号
    • 對于輸入參數和inout參數的輸入,設計預設為ap_none
    • 對于輸出參數和inout參數的輸出,設計實作類型為ap_vld

ap_memory, bram

ap_memory和bram接口端口級I/O協定用于實作數組參數。 當需要随機通路記憶體位址位置時,這種類型的端口級I/O協定可以與存儲元件(例如RAM和ROM)通信。

注意:如果隻需要對存儲元素的順序通路,請改用ap_fifo接口。 ap_fifo接口可減少硬體開銷,因為不執行位址生成。

ap_memory和bram接口端口級别的I/O協定是相同的。 唯一的不同是Vivado IP內建器顯示塊的方式:

  • ap_memory接口顯示為離散端口
  • bram接口顯示為單個分組端口,在IP內建器中,可以使用單個連接配接來建立到所有端口的連接配接

使用ap_memory接口時,請使用RESOURCE指令指定數組目标。 如果沒有為陣列指定目标,則Vivado HLS會自動決定是使用單端口還是雙端口RAM接口。(TIP提示:在運作綜合之前,請確定使用RESOURCE指令将數組參數定位到正确的記憶體類型。 使用更正後的記憶體進行重新合成可能會導緻時間表和RTL不同)

下圖顯示了一個名為d的數組,該數組指定為單端口Block RAM, 端口名稱基于C函數中的參數名稱。 例如,如果C參數名為d,則片使能命名為d_ce;基于BRAM的output / q端口,輸入資料會命名為d_q0。

接口綜合參考(Interface Synthesis Reference)

複位完成後,将發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 在置位輸出信号d_ce的同時,通過在輸出位址端口上給位址來執行讀取(注意:對于預設的Block RAM,設計期望輸入資料d_q0在下一個時鐘周期可用。 您可以使用RESOURCE指令來訓示RAM具有更長的讀取延遲)
  • 寫操作通過置位輸出端口信号d_ce和d_we來執行,同時給出位址和輸出資料d_d0

ap_fifo

若一個輸出端口被寫入,當設計需要通路存儲元件并且通路總是以順序的方式進行時,即不需要随機通路時,與其相關聯的輸出有效信号接口是最節省硬體的方法。 ap_fifo端口級I/O協定支援以下内容:

  • 允許端口連接配接到FIFO
  • 實作完整的雙向空滿通訊
  • 适用于數組,指針和按引用傳遞參數類型

注意:可以使用ap_fifo接口的函數通常使用指針,并且可以多次通路相同的變量。 若要了解使用這種編碼樣式時volatile限定符的重要性,請參考:《Mult-Access Pointer Interfaces: Streaming Data》。

在下面的示例中,in1是一個指針,該指針通路目前位址,然後通路目前位址的上兩個位址,最後通路下一個位址。

void foo(int* in1, ...) {
	int data1, data2, data3;
	...
	data1= *in1;
	data2= *(in1+2);
	data3= *(in1-1);
	...
}
           

如果将in1指定為ap_fifo接口,則Vivado HLS會檢查通路的方式,确定通路不是按順序進行的,然後發出錯誤資訊并暫停。 要從 非順序位址位置 讀取資料,需要使用 ap_memory 或 bram 接口。

您不能在讀寫(既要讀又要寫)的參數上指定ap_fifo接口。 您隻能在輸入或輸出參數上指定ap_fifo接口。輸入參數為in且輸出參數為out且都指定為ap_fifo的設計的行為如下圖所示。

接口綜合參考(Interface Synthesis Reference)

對于輸入,發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 如果輸入端口已準備好讀取但FIFO空,即輸入端口in_empty_n置位低電平,則設計将停頓并等待資料可用
  • 當FIFO包含輸入端口in_empty_n高訓示的資料時,輸出确知信号in_read會被置為高,以訓示在此周期中已讀取資料

對于輸出,發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 如果輸出端口已準備好寫入,但FIFO已滿,即out_full_n置位低電平,則将資料放置在輸出端口上,但設計将停頓并等待FIFO中的空間可用
  • 當FIFO中有可用空間時,即out_full_n置位高電平,輸出确知信号out_write會被置位以訓示輸出資料有效
  • 如果使用 -rewind 選項對頂層函數或頂層循環進行了流水線處理,則Vivado HLS将建立帶有字尾 _lwr 的附加輸出端口。 當最後一次寫入FIFO接口完成時,_lwr 端口變為高電平有效。

ap_bus

ap_bus 接口可以與總線橋進行通信。 由于ap_bus接口未遵循特定的總線标準,是以可以将此接口和與系統總線進行通信的總線橋一起使用,其中總線橋必須能夠緩存所有突發寫入。

注意:可以使用ap_bus接口的函數使用指針,并且可能多次通路同一變量。 若要了解使用這種編碼樣式時volatile限定符的重要性,請參考:《Mult-Access Pointer Interfaces: Streaming Data》。

您可以通過以下方式使用ap_bus接口:

  • 标準模式:此模式執行單獨的讀取和寫入操作,并指定每個操作的位址
  • 突發模式:如果在C源代碼中使用了C函數 memcpy ,則此模式将執行資料傳輸。 在突發模式下,該接口訓示基址和傳輸大小, 然後以連續的周期傳輸資料樣本

注意:通過memcpy函數通路的數組不能劃分為寄存器。

以下示例顯示了将 ap_bus 接口應用于參數 d 時标準模式下的讀寫操作的行為。

void foo (int *d) {
	static int acc = 0;
	int i;
	for (i=0;i<4;i++) {
		acc += d[i+1];
		d[i] = acc;
	}
}
           

以下示例顯示了使用C函數memcpy和突發模式時的行為。

void bus (int *d) {
	int buf1[4], buf2[4];
	int i;
	memcpy(buf1,d,4*sizeof(int));
	for (i=0;i<4;i++) {
		buf2[i] = buf1[3-i];
	}
	memcpy(d,buf2,4*sizeof(int));
}
           

① 标準模式下的ap_bus讀取操作行為如下圖所示。

接口綜合參考(Interface Synthesis Reference)

複位完成後,将發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 如果必須執行讀取但總線橋FIFO中沒有資料(即d_rsp_empty_n為低電平),則會發生以下情況:
    • 輸出端口d_req_write被置高電平,輸入端口d_req_din保持低電平,以訓示要進行一個讀取操作
    • 輸出位址d_address
    • 設計停頓并等待資料可用
  • 當資料變得可用于讀取輸出信号時,d_rsp_read立刻置位并在下一個時鐘沿讀取資料
  • 如果必須執行讀取并且總線橋FIFO中有可用資料(由d_rsp_empty_n高訓示),則會發生以下情況:
    • 輸出端口d_req_write被置為有效,而端口d_req_din被置為無效以訓示讀取操作
    • 輸出位址
    • 輸出信号d_rsp_read在下一個時鐘周期有效,然後設計的塊在下一個時鐘沿讀取資料

② 标準模式下的ap_bus寫資料操作行為如下圖所示。

接口綜合參考(Interface Synthesis Reference)

複位完成後,将發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 如果必須執行寫操作,但總線橋FIFO中沒有空間(即d_req_full_n為低電平),則會發生以下情況:
    • 輸出位址和資料
    • 設計停頓并等待空間可用
  • 當空間變得可用于寫入時,将發生以下情況:
    • 輸出端口d_req_write和d_req_din被置位以訓示寫操作
    • 輸出信号d_req_din立刻被置位以訓示該資料在下一個時鐘沿有效
  • 如果必須執行寫操作并且總線橋FIFO中有可用空間(即d_req_full_n為高電平),則會發生以下情況:
    • 輸出端口d_req_write和d_req_din被置位以訓示寫操作
    • 輸出位址和資料
    • 輸出信号d_req_din被置位以訓示資料在下一個時鐘沿有效

③ 突發模式下的ap_bus讀取資料操作行為如下圖所示。

接口綜合參考(Interface Synthesis Reference)

複位完成後,将發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 如果必須執行讀取但總線橋FIFO中沒有資料(d_rsp_empty_n為低電平),則會發生以下情況:
    • 輸出端口d_req_write被置高電平,輸入端口d_req_din保持低電平,以訓示要進行一個讀取操作
    • 輸出傳輸基位址和傳輸大小
    • 設計停頓并等待資料可用
  • 當資料可用于讀取時,輸出信号d_rsp_read立刻置位并在接下來的N個時鐘沿讀取資料,其中N是關于傳輸大小的輸出端口的值
  • 如果總線橋FIFO的值空了,資料傳輸将立即停止并等待直到資料可用為止

④ 突發模式下的ap_bus寫入資料操作行為如下圖所示。

接口綜合參考(Interface Synthesis Reference)

複位完成後,将發生以下事件:

  • 開始信号ap_start置高後,塊開始正常操作
  • 如果必須執行寫操作,但總線橋FIFO中沒有空間(即d_req_full_n為低電平),則會發生以下情況:
    • 輸出基位址、傳輸大小和資料
    • 設計停頓并等待空間可用
  • 當空間變得可用于寫入時,将發生以下情況:
    • 輸出端口d_req_write和d_req_din被置位以訓示寫操作
    • 輸出信号d_req_din立刻被置位以訓示該資料在下一個時鐘沿有效
    • 如果FIFO已滿,則輸出信号d_req_din立即置為無效,并在有可用空間時将其置為有效
    • 傳輸完N個資料值後,傳輸停止,其中N是關于傳輸大小的輸出端口的值
  • 如果必須執行寫操作并且總線橋FIFO中有可用空間(即d_rsp_full_n為高電平),則傳輸開始,直到FIFO已滿時設計才停止操作

axis

axis模式指定了AXI4-Stream I/O協定。 有關AXI4-Stream接口的完整描述,包括時序和端口,請參見《 Vivado Design Suite: AXI Reference Guide》(UG1037)。 有關使用此I/O協定的完整功能的資訊,請參考《Using AXI4 Interfaces》。

s_axilite

s_axilite模式指定AXI4-Lite slave I/O協定。有關AXI4-Lite slave接口的完整描述,包括時序和端口,請參見《 Vivado Design Suite: AXI Reference Guide》(UG1037)。有關使用此I/O協定的完整功能的資訊,請參考《Using AXI4 Interfaces》。

m_axi

m_axi模式指定AXI4 master I/O協定。有關AXI4 master接口的完整描述,包括時序和端口,請參見《 Vivado Design Suite: AXI Reference Guide》(UG1037)。有關使用此I/O協定的完整功能的資訊,請參考《Using AXI4 Interfaces》。