這個範例屬性的所有核心功能都包含在 FPGA 程式碼裡面。 這個 FPGA 程式碼在初階層級實作了類比輸入、類比輸出、計數器與數位 I/O 工作項目,每一個項目皆包含在 NI LabVIEW FPGA 程式碼的個別迴圈中。 下列段落說明了 FPGA 程式碼的運作方式。 雖然會分別說明程式碼的不同元件,但請記得這些元件都位於同一個 FPGA VI 裡面。
圖 1. 類比輸入迴圈
外圍的 While Loop 僅會輪詢 AI Enable Boolean 值。 一旦 Boolean 值變成 True,就會開始執行類比擷取作業。 內圈的 While Loop 才是真正控制資料擷取的部分。 內圈的 While Loop 採用平面順序架構 (Flat Sequence Structure),共有兩個框架。 我們在第一個框架中設定迴圈速率,這樣一來迴圈即使用此取樣率。 這個框架還有其他的邏輯,方便使用者了解迴圈的運轉速度。
順序架構的第二個框架會同時擷取每個通道 (通道 0–7) 的一個樣本,並且把這 8 個樣本建置為一個 1D 陣列。 接著此陣列會輸入一個單週期 Timed Loop。 此迴圈會針對使用者想要擷取資料的通道運作一次。 舉例來說,如果使用者想要擷取通道 0、1、7 的資料,單週期 Timed Loop 就會運作三次。 每次迴圈運作的時候,就會把一個樣本寫入類比輸入 DMA FIFO。 下一次重複運作則會等候 Loop Timer 指示,直到可以開始擷取下一個資料點為止。
一旦 AI Enable Boolean 值變成 False,就會停止擷取資料,並且交由外圍迴圈主導,直到 AI Enable 再次增加,並且開始擷取資料為止。 如果想要把資料寫入已滿的 AI FIFO,我們會停止擷取資料,並且把 AI Buffer Overflow? 指示元件設為 True。 此外,每次寫入資料至 AI FIFO 的時候,就會增加一個計數器。 這樣一來,即可知道有多少資料放入緩衝區,Host VI 也可以在每次有限擷取作業之間有效刷新緩衝區。
圖 2. 類比輸出迴圈
和類比輸入迴圈一樣,外圍的 While Loop 僅會輪詢 AO Enable Boolean 值。 一旦 Boolean 值增加,就會開始執行類比輸出作業。 內圈的 While Loop 才是真正控制類比輸出的部分。 這個迴圈採用平面順序架構 (Flat Sequence Structure),共有兩個框架。 第一個順序架構的框架僅會設定迴圈速率,這樣一來迴圈即可以使用者所選的適當輸出頻率運作。
第二個順序架構的框架則會針對使用者選為緩衝輸出的通道,讀取其中的 DMA FIFO 輸出項目。 舉例來說,如果使用者選用 0、1、7 類比輸出通道,While Loop 就會運作三次,並且把每個值放入 8 元素陣列中的適當位置。
這個迴圈之後的下一個邏輯區段看起來很複雜,其實很簡單。 首先我們把 AO Buffer Enable 輸入值轉換成 8 個 Boolean 值所組成的陣列。 此陣列中每一個 Boolean 值都會對應到 8 個類比輸出通道之一。 舉例來說,如果此陣列的元素 0 是 TRUE,代表 AO 通道 0 已設為緩衝通道,我們應該對此通道輸出來自 AO FIFO 的資料。 但如果此陣列的元素 0 是 FALSE,代表 AO 通道 0 已設為軟體時序 (非緩衝) 通道。 如果某通道設為非緩衝 (FALSE),我們僅能對此通道 (AO 0) 的對應控制元件中輸出數值。 這個程式碼段落的邏輯會根據 AO Buffer Enable Boolean 值來確認通道,如果是 TRUE,就會把數值從 FIFO 讀取元件路由至通道 (透過 Select 函式)。 如果是 FALSE,就會把對應的通道控制元件路由至輸出。
如果使用者把 AO Enable Boolean 值設為 FALSE,或是緩衝區出現虧位 (underflow),類比輸出作業就會停止。 離開此迴圈之後,程式碼就會等候 AO Enable 變成 False (也就是緩衝區虧位),並且讀取 FIFO 直到淨空為止,藉此清除 AO FIFO。 如果要此邏輯運作,Host VI 必須確保在 AO Enable 設為 False 之後,不會有新的資料點輸入 AO DMA FIFO,直到完成下一次類比輸出為止。
一旦類比輸出作業結束之後,外圍迴圈就會再次主導並輪詢 AO Enable Boolean 值,直到 Boolean 值再次增加,並且開始執行下一次類比輸出作業為止。
圖 3. 計數器迴圈
這個範例屬性共有 4 個獨立計數器。 每一個計數器都會在 LabVIEW FPGA 中採用相同迴圈實作而成。
和上述迴圈一樣,計數器迴圈的外圍迴圈會先開始輪詢 Counter 0:Enable Boolean 值。 一旦 Boolean 值變成 True,就會開始執行計數器作業。 計數器包含了單週期 Timed Loop,並且針對每次 40 MHz 內建時脈的執行週期運作一次。 在這個單週期 Timed Loop 裡面,計數器大多數的工作項目都會在 Advanced Counter Sub subVI 完成。 主程式必須提供輸入項目給計數器,以便決定計數器的運作方式, 其中包含下列參數:
Advanced Counter Sub 的輸出值包含了目前的計數器數值與 Counter Reset 訊號。 如果 Advanced Counter Sub VI 重設計數器的話,Counter Reset 就會變高。 這樣一來,我們就會手動把 Counter 0:Reset Counter 輸入設為 False。 這麼做可以避免計數器持續重新設定,直到使用者手動重設 Counter 0:Reset Counter 輸入為止。
一旦 Counter 0:Enable 訊號變成 False,我們就會退出單週期 Timed Loop,外圍迴圈就會開始輪詢 Counter 0:Enable 輸入,直到此數值變高為止。 一旦 Counter 0:Enable 再次變高,會先重設計數器,並且開始重新計算。
圖 4. 數位 I/O 迴圈
目前為止,數位 I/O 迴圈是整個 FPGA 程式碼中最簡單的迴圈。 此迴圈會讀取 5 個 8 位元數位輸入埠,並且撰寫至 5 個不同的指示元件。 此外也會取得 5 個 8 位元控制元件的數值,並且撰寫至 5 個輸出。 此迴圈可以最高速度自行運作,不會停下來。
如要使用 FPGA 屬性,必須有一個可以與 FPGA VI 通訊的主機。 這個屬性也包含了數個 Host VI,可各自說明不同的屬性功能。 下列段落列出了所有的主機範例、使用方法,以及程式方塊圖的運作方式。
圖 5. Cont Acq&Graph Voltage-Int Clk.vi 人機介面
圖 6. Cont Acq&Graph Voltage-Int Clk.vi 程式方塊圖
此範例說明了如何執行簡易的連續類比擷取作業。 這個 VI 的人機介面和類似功能的 DAQmx VI 很像。 必須選擇想要通訊的裝置、要讀取的通道、取樣率,以及要從緩衝區立即讀取的樣本數量。
觀察這個程式方塊圖之後,首先我們會開啟 FPGA VI 參考。 這樣一來即可把 FPGA 程式碼下載至 R 系列介面卡並開始運作。 之後我們會設定主機端 DMA FIFO 的深度。 就此範例而言,我們會把深度設為 32,767 個元素。 也就是說,主機電腦的緩衝區可容納 32,767 個樣本 (包含所有通道在內)。
接著我們會呼叫 AI FIFO: Start,藉此開始 DMA 程序。 這樣一來即可確保 FPGA 開始擷取樣本時,就會在背景把這些樣本從 FPGA 記憶體傳送到主機記憶體。 之後我們會設定 AI 迴圈計時器來指定資料擷取速度,接著設定 AI Channel Enable,以便告訴 FPGA 我們想要讀取 8 個 AI 通道中哪些通道。 最後我們會把 AI Enable 設為 True,開始擷取作業。
在此迴圈中,我們會讀取指定數量的 FIFO 樣本,並且把這些樣本輸入 AI Data to Array subVI。 這個 subVI 會清除來自 FIFO 的 1D 陣列,並且建置合適的 2D 陣列以便輸入波形圖。 我們還會在此迴圈中,檢查有無緩衝區溢位的的問題,並且回復到 FPGA 所運作的實際迴圈速度。 在下列三個情況下會停止: 使用者點選 Stop 按鈕、緩衝區溢位,或者其他錯誤發生。
一旦主迴圈停下來,我們就會關閉 FPGA 參考,並且重新設定 FPGA (停止 FPGA VI)。 最後,我們會顯示任何可能的問題給使用者。
圖 7. Acq&Graph Voltage-Int Clk-Retrigger 人機介面
圖 8. Acq&Graph Voltage-Int Clk-Retrigger 程式方塊圖
Acq&Graph Voltage-Int Clk-Retrigger 範例和上一個很像,但不是連續擷取電壓樣本,而是在每次點選 Trigger 按鈕時,擷取有限數量的樣本。
一旦開啟 FPGA VI 參考並執行 FPGA VI 之後,就會進入主迴圈。 主迴圈包含一個事件架構,等候 Trigger 按鈕被按下。 一旦點選此按鈕,就會設定擷取作業的參數,並且以特定的 AI FIFO 點數加以讀取。
完成讀取所有的資料點,並且把 AI Enable 設為 False 以便停止擷取資料之後,就會進入這個程式碼真正有趣的地方。 接著我們進入 Flush FIFO 迴圈。 此迴圈會執行,並且讀取可能已寫入 FIFO、但我們想要在下次重複執行之前自 FIFO 清除的額外資料。 刷新 FIFO 之後,我們會返回主迴圈,並且等候 Trigger 按鈕再次被按下。 一旦使用者點選 Stop 按鈕,我們就會退出迴圈,關閉 FPGA 參考 (此步驟會讓 FPGA 程式碼停止運作)。
圖 9. Gen Mult Voltage Update.vi 人機介面
圖 10. Gen Mult Voltage Update.vi 程式方塊圖
Gen Mult Voltage Updates 主機範例說明了如何透過最簡單的方式,使用這個 FPGA 屬性完成類比輸出作業。 開啟 FPGA VI 參考並執行之後,只要把 AO Enable 設為 True,並且指定類比輸出迴圈在 FPGA 上的運作速度即可。 一旦進入主迴圈,就會校準 AO Channels 陣列的資料,並且把資料寫入 FPGA 內的 AO 控制元件。
圖 11. Cont Gen Voltage Wfm-Int Clk-Non Regeneration 人機介面
圖 12. Cont Gen Voltage Wfm-Int Clk-Non Regeneration 程式方塊圖
Cont Gen Voltage Wfm-Int Clk-Non Regeneration 範例比較複雜一點,可顯示 FPGA 屬性的硬體時序類比輸出功能。 在此範例中,我們先開啟 FPGA VI 參考,但是不執行此項目。 接著我們設定類比輸出迴圈計時器與 AO Buffer Enable。 之前的段落提到,AO Buffer Enable 輸入可告訴 FPGA 程式碼哪些通道可做為緩衝 (硬體時序) 輸出,哪些可做為靜態 (軟體時序) 輸出。 接著我們把 AO Enable 設為 TRUE。 一般來說,這麼做即可在 FPGA 執行類比輸出,但因為 FPGA 程式碼並未運作,所以不會啟動類比輸出作業。
接下來要產生特定波形類型的樣本,並且撰寫至 AO FIFO。 一旦 FPGA 開始運作,FIFO 就會備有初始資料。 如果我們等到 FPGA VI 啟動之後才撰寫資料至 FIFO,很有可能會遇到緩衝區處理中且來不及準備的問題,FPGA 會在我們放入資料之前就嘗試讀取 FIFO 資料。
一旦 FIFO 有了初始資料之後,我們就會呼叫 FPGA 的 Run 方式,並且啟動 FPGA 程式碼。 因為我們已經把 AO Enable 設為 TRUE,一旦我們呼叫這個方式,類比輸出作業就會立即啟動。 我們會在 While Loop 監控實際的迴圈速率,並且輸入更多資料至類比輸出 FIFO。 就此範例而言,相同的波形會輸入全部 8 個通道。 一旦使用者點選 Stop 按鈕,就會退出此迴圈,並且關閉 FPGA 參考。
圖 13. Count Digital Events.vi 人機介面
圖 14. Count Digital Events.vi 程式方塊圖
Count Digital Events 說明了如何使用 FPGA 屬性的計數器。 首先我們開啟並執行 FPGA 程式碼參考。 接著設定計數器參數 (起始數值、濾波器次數等等)。 最後我們把 Counter 0:Enable 設為 TRUE,計數器就會開始運作。
接著我們會進入主要 While Loop。 此迴圈只會讀取計數器的數值,而且使用者可以重新設定計數器數值。 使用者點選 Stop 按鈕之後,就會關閉 FPGA 參考,結束這項應用程式。
圖 16. Write Dig Chan.vi 程式方塊圖
Write Dig Chan Host VI 說明了如何使用這個 FPGA 屬性,完成簡易的數位輸出作業。 我們在程式方塊圖中開啟 FPGA 參考並執行 FPGA VI。 接著進入主迴圈,並且把 Data to Write 控制元件的數值寫入 Connector 2:DIO Port 0,每秒鐘寫入十次。 點選 Stop 按鈕之後,就會關閉 FPGA 參考,FPGA VI 也會停下來。
圖 18. Read Dig Chan.vi 程式方塊圖
Read Dig Chan 範例說明了如何使用這個 FPGA 屬性的數位輸入功能。 我們先開啟 FPGA VI 參考,並且啟動 FPGA 程式碼。 接著進入主迴圈,每秒讀取數位埠十次。 使用者點選 Stop 按鈕之後,就會退出迴圈,並且關閉 FPGA 參考。
平衡式 I/O 範例 DAQ 屬性說明了 R 系列介面卡搭配 LabVIEW FPGA 的用途。 其他裝置無法透過單一硬體提供 8 個類比輸入、8 個類比輸出、4 個簡單事件計數器 (配備抖動消除濾波器)、40 個數位輸入通道、40 個數位輸出通道。 不需要 LabVIEW FPGA Module 即可使用這個預先編譯的屬性, 但如果要修改 FPGA 程式碼,就會需要此模組。 NI-RIO 驅動程式是唯一必備的驅動程式。
Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.