接口綜合參考(Interface Synthesis Reference)


本博客解釋了每種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語法,這一個端口就不會生成。

在這裏插入圖片描述

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)信號的行爲。

在這裏插入圖片描述

復位完成後,將發生以下事件:

① 所設計的塊等待 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聲明爲高爲止。

在這裏插入圖片描述

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。
在這裏插入圖片描述
對於輸入,發生以下事件:

  • 開始信號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。

在這裏插入圖片描述
復位完成後,將發生以下事件:

  • 開始信號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_memorybram 接口。

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

在這裏插入圖片描述

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

  • 開始信號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讀取操作行爲如下圖所示。
在這裏插入圖片描述

復位完成後,將發生以下事件:

  • 開始信號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寫數據操作行爲如下圖所示。

在這裏插入圖片描述
復位完成後,將發生以下事件:

  • 開始信號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讀取數據操作行爲如下圖所示。

在這裏插入圖片描述
復位完成後,將發生以下事件:

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

④ 突發模式下的ap_bus寫入數據操作行爲如下圖所示。

在這裏插入圖片描述
復位完成後,將發生以下事件:

  • 開始信號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》。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章