跳至內容

位元 Arithmetic#

本主題說明在由VisualApplets 設計所產生的FPGA管線中,位元寬度的運作方式。閱讀完本主題後,您將了解位元寬度如何限制算術結果、如何處理溢出,以及如何使用型別轉換、截斷和位移運算子來控制數值範圍。您還將了解有符號與無符號數值的差異、定點數的運作原理,以及如何從較寬的資料字中提取位元欄位。

關鍵術語

位元寬度是指每個像素或連結上每個值所對應的位元數。位元寬度決定了值的範圍。例如,一個 8 位元的無符號連結所承載的值範圍為 0 到 255。Arithmetic 溢出是指算術運算結果已超出可用位元範圍。此時,結果會發生迴圈(即數值歸零)或丟失高位元。

有關連結屬性與參數依賴關係,請參閱「參數化教學」章節。關於連結背後的正式規則,請參閱《使用者手冊》中的「連結規則」。

每個 link 兩個模組(即已實例化的運算子)之間的 Bit Width 屬性。此屬性定義所產生的 FPGA 管線針對該連接上的每個像素或值所使用的位元數。對於色彩連結,位元寬度涵蓋所有色彩成分的總和。在具有 ImageProtocol = VALT_SIGNAL, 位寬始終為 1 位元。

每個資料字,連結最多支援64 位元。當運算子計算出的結果位寬超過此限制時,必須在連結位寬超過此限制之前,對資料進行截斷、型別轉換或位移操作。

並非每個運算子都支援所有位元寬度。某些運算子僅允許特定的位元範圍,例如 1 至 64 位元、8 位元、12 位元或 16 位元。 《運算子參考》中的「支援的連結格式」表格記載了各運算子允許的數值範圍。您也可以在設計窗格中右鍵點擊模組並選擇「說明」,或按下F1 鍵,開啟運算子說明。此內容與《運算子參考》相同,並作為VisualApplets 中的工具內說明提供。

當出現位寬衝突時,請先檢查上游運算子的輸出連結。調整該 Bit Width 運算子上的連結屬性,可讓您編輯該屬性,或插入一個運算子,例如 CastBitWidth, ClipHigh, ClipLow, ShiftLeft,或 ConvertPixelFormat 以變更路徑沿線的位元寬度。

連結屬性會沿著處理管線傳播,直到有運算子將其變更為止。請在相機輸出連結上設定寬度,或在處理路徑中插入位元寬度運算子。請參閱「連結屬性的傳播」教學主題。

Arithmetic 運算的位元寬度#

Arithmetic 函式庫中的運算子會推導出輸出結果 Bit Width 自動地。該 Supported Link Format 表格位於 Operator 參考手冊 將這些輸出標記為 auto. 通常無法直接在連結上編輯這些輸出位寬的連結屬性。若您希望在算術運算後手動變更位寬,請使用額外的運算子,例如 CastBitWidth 配合 ClipHigh 以及/或 ClipLow. 以下算術運算子也會改變位元寬度:

加法與減法#

當 ADD 此運算子會將所有輸入連結上的像素值相加。該 SUB 此運算子會將第二個輸入的像素值從第一個輸入中減去。

VisualApplets 根據輸入位元寬度設定輸出位元寬度。結果將比該最大值寬 1 位元。若在 ADD, 輸出可能需要多一個位元。

「加法運算子」—— 加總像素值

輸出位元寬度不得超過 64 位元。在 ADD 或 SUB, 請檢查下游連線中傳遞的連結寬度。

乘法#

當 MULT 此運算子會將其兩個輸入端的像素值進行乘法運算。單一連結的輸入位元寬度上限為 32 位元。輸出位元寬度等於兩個輸入位元寬度的總和。將 8 位元值與 8 位元值相乘,會產生 16 位元的結果:

使用 MULT 運算子變更Bit Width

資訊

MULT 會佔用大量 FPGA 資源。若要進行常數縮放,Basler 建議 SCALE 或 ShiftLeft 。

Division#

當 DIV 運算子會將輸入連結上的值進行除法運算 I1 根據輸入連結中的數值 I2. 輸出連結 O 攜帶整數商。輸出連結 R 攜帶進位。在兩個輸出端,除以零的運算結果均未定義。

輸入鏈路的位寬 I2 必須小於或等於輸入鏈路的位元寬度 I1. 對於無符號輸入,輸出鏈路上的輸出位元寬度為 O 等於輸入鏈路的位元寬度 I1. 對於帶符號的輸入,輸出鏈路上的輸出位寬為 O 等於輸入位元寬度 I1 加一。

DIV 運算子搭配無符號輸入連結時的位元寬度

DIV 執行整數除法。此運算本身不會保留小數位。若要進行固定小數點除法,請使用 ShiftLeft 在進行除法運算之前,請先輸入運算子。

有關小數值的詳細資訊,請參閱本主題中「固定點Arithmetic」一節。

資訊

DIV 會佔用大量 FPGA 資源。若要執行以 2 的冪次為除數的除法,請使用 ShiftRight 。

使用 Clip 和 Cast 運算子處理 `Arithmetic ` 溢出問題#

Arithmetic 當計算結果超出當前位元寬度所能表示的範圍時,便會發生 溢出。在 8 位元無符號連結中,其範圍為 0 至 255。200 + 100 的和等於 300。若輸出位元不足,儲存的數值便會出錯。溢出會以錯誤的像素值呈現:

位元溢出

Arithmetic 溢出 不應與由 Overflow 運算子位於 同步 函式庫:該 Overflow 此運算子用於對無法停止的來源進行流量控制。有關此 Overflow 運算子,請參閱 可停止與不可停止的資料串流 教學主題。

您可以使用以下運算子來修正算術溢出問題:

ClipHigh 與 ClipLow#

當 ClipHigh 此運算子會將數值限制在可設定的最大值內。任何超過最大值的輸入值,都會被替換為該最大值。該 ClipLow 此運算子在可設定的最小值情況下,運作方式類似。

使用 ClipHigh 進行明確的生命週期管理即呼叫 ClipLow 將數值維持在目標範圍內 之前 減少位元寬度。請透過模組參數設定剪輯限制。有效範圍取決於 Bit Width 輸入連結的屬性,以及該輸入連結是否採用有符號或無符號運算。

螢幕截圖顯示, ClipHigh 將所有大於 255 的像素值設為 255:

ClipHigh 運算子會計算所有像素值,使其符合指定範圍

CastBitWidth#

當 CastBitWidth 此運算子會變更鏈結位元寬度。您可設定鏈結屬性 Bit Width 在運算子的輸出鏈路上。

當輸出位元寬度大於輸入位元寬度時,運算子會保留該值,並在最高位元位置補入位元。對於有符號數, CastBitWidth 執行符號擴展。

當輸出位元寬度小於輸入位元寬度時, CastBitWidth 捨棄最高位元。因此,無法在輸出位元寬度內表示的數值將會被修改。由於此操作會永久移除位元,後續處理所需的信息可能會遺失。

在減少鏈路位寬時,Basler 建議按照以下順序執行下列步驟:

  1. 插入 ClipHigh 進行明確的生命週期管理即呼叫 ClipLow 將位元寬度值限制在目標範圍內。
  2. 插入 CastBitWidth 以減少位元寬度。

另請參閱「參數化教學」主題。

範例:增加像素並縮小結果#

此範例將兩個 8 位元無符號像素資料流相加,並傳回一個 8 位元的結果供後續處理:

  1. 將兩個 8 位元影像路徑連接至一個 ADD 運算子。
  2. 請檢查輸出連結。 ADD 產生一個 9 位的結果。
  3. 插入 ClipHigh 之後 ADD. 將最大值設定為 255。
  4. 插入 CastBitWidth 之後 ClipHigh. 設定輸出 Bit Width 至 8。
  5. 執行第 1 級設計規則檢查,並確認所有連結均有效。

沒有 ClipHigh, CastBitWidth 只會捨棄第九位元,因此大數相加會產生錯誤的像素值。

將 ClipHigh 與 CastBitWidth 結合使用可避免產生錯誤的結果資料

有符號與無符號數值#

link 屬性 Arithmetic 指定所產生的 FPGA 管線是否將數值視為 Signed 或 Unsigned. 關於 Signed,該硬體採用二進位補碼表示法。您可在設計階段於「VisualApplets 」中設定此屬性。

符號位是已設定位元寬度的一部分。

9 位元數值,其中 1 位元保留用於標誌資訊

當 CastType 運算子會變更該 Arithmetic 輸出連結上的連結屬性。位元模式保持不變。生成的 FPGA 邏輯不會改變儲存的位元模式,因此該運算子不會佔用任何 FPGA 資源。

根據算術設定的不同,相同的位元模式可能代表不同的十進位數值。該數值 1010 在 4 位元無符號鏈路上,此模式等於 10。而在 4 位元有符號鏈路上,相同的模式等於 −6。

請使用 CastType 當下游運算子需要不同的算術類型,且數值範圍仍符合時,會使用此運算子。

CastType 將 `Arithmetic ` 的值從有符號型別變更為無符號型別

檢查值是否落在位元範圍內#

在VisualApplets 中,參數值(例如, CONST 運算子) 會以十進位數的形式輸入並顯示。然而,連接至運算子的連結僅能儲存特定位元範圍內的值。因此,請確保參數值能容納於所連接連結的位元寬度內。

未簽名的連結

一個 n 位元無符號數只能表示正數和零。其有效範圍為:

0 到 2^n − 1

舉例來說,一個 8 位元無符號數值可以儲存 0 到 255 之間的數值:

8 位元無符號數的最大值

關於與……的關係 ImageProtocol = VALT_SIGNAL,這個算式總是 Unsigned.

簽名連結

一個 n 位元有符號連結可表示正值與負值。其有效範圍為:

−2^(n-1) 到 2^(n-1) − 1

例如,一個 8 位元有符號的連結可儲存從 −128 到 127 的值。

8 位元有符數的最大值

最高位用作符號位,用以指示該值是正數還是負數。

定點數Arithmetic#

VisualApplets 用於建立在 FPGA 上實作的影像處理設計。與在個人電腦上運行的軟體不同,FPGA 硬體通常不支援浮點數(例如 0.5 或 1.25)。相反地,計算通常是使用整數進行的。

為了在維持整數運算的同時表示分數值,VisualApplets 採用固定小數點表示法。這使得諸如縮放係數、增益或次像素座標等值,能夠在硬體中高效地儲存與處理。

本節說明:

  • 為何需要固定點表示法。
  • 小數值如何以整數位元模式儲存。
  • Q 格式如何定義小數點的位置。
  • 位寬如何影響可用數值範圍與精確度。
  • 運算子選擇如何影響計算的準確性。

透過連線傳輸的每個值,都會以一串位元的形式儲存。硬體會將這些位元解讀為一個整數值。

例如,以下位元模式代表整數值 5:

00000101 = 5

然而,影像處理應用程式通常需要使用分數值,例如: 0.5, 1.25,或 12.75.

由於 FPGA 不儲存浮點數,因此這些數值會以定點格式表示。在定點表示法中,位元模式仍以整數形式儲存,但您需為小數點定義一個固定位置。

儲存的整數值仍然是 5,但其解釋方式為:

5 / 2^2 = 1.25

因為有兩個位元是預留給小數部分的。

你可以將此視為一個 虛擬小數點 該位置是固定在預先定義的位置上。在二進位算術中,此分界點即為二進位小數點,位於各位元權重之間 2^0 進行明確的生命週期管理即呼叫 2^-1. 本教學保留了這個熟悉的術語 虛擬小數點. FPGA 會使用整數進行所有運算,而您則需根據所選的固定小數點格式來解讀結果。

Q 格式與位元分配#

定點數透過將部分位元分配給整數部分,另一部分位元分配給小數部分,來表示小數值。虛擬小數點的位置則使用Q 格式來描述。

Q 格式的寫法如下:

Qm.n

其中:

  • m 是整數位元的數量
  • n 是小數位數

對於有符號數值,符號位包含在整數部分之中。

例如:

Q4.4

意指:

  • 4 位元用於整數部分
  • 小數部分佔 4 位元
  • 總共 8 位元

小數位數決定了所表示數值的精確度。

可表示的最小步長為:

1 / 2^n

其中 n 是小數位數。

範例:

格式 分數位元 最小步長
Q6.2 2 0.25
Q4.4 4 0.0625
Q2.6 6 0.015625

小數位數越多,相鄰數值之間的差異就越小,因此精確度也越高。

總位寬是固定的。因此,用於小數部分的位元將無法再用於整數部分。

因此:

  • 分數位數越多,精確度越高,但可用的整數範圍會隨之減少。
  • 小數位數越少,整數範圍越大,但精確度越低。

選擇 Q 格式時,應在所需的數值範圍與所需的精度之間取得平衡。

在定點數中,每個位元都代表二的冪次。

虛擬小數點左側的位元代表整數:

..., 2^3, 2^2, 2^1, 2^0

向右的位元代表分數:

2^-1, 2^-2, 2^-3, ...

例如,以 Q4.4 格式表示:

Bit position:  7   6   5   4   3    2     1      0
Weight:      2^3  2^2  2^1  2^0  2^-1  2^-2  2^-3  2^-4

該地點的 2^0 該位元定義了虛數小數點的位置。此位置並未儲存於硬體中;它由所選的 Q 格式所定義,且必須在整個設計中保持一致的詮釋。

範例:Q4.4#

在 Q4.4 格式中,4 位元用於整數部分,4 位元用於小數部分。

位元模式

0 0 0 0 . 1 0 0 0

包含一個 1 在第一個小數位。此位置代表該值 2^-1, 其等於 0.5.

因此,該位元模式代表:

0 * 2^0 + 1 * 2^-1 + 0 * 2^-2 + 0 * 2^-3 + 0 * 2^-4 = 0.5

雖然所表示的數值是 0.5, FPGA 僅儲存對應的整數值:

Stored integer value: 8
Represented real value: 0.5

這之所以能運作,是因為 Q4.4 使用 4 位分數位元。儲存的整數值會被解釋為:

Real value = Stored integer / 2^4
           = 8 / 16
           = 0.5

讓 F 設為小數位數。

要將實數轉換為其定點表示法:

FixedPoint = round(RealValue * 2^F)

範例:

FixedPoint = round(0.5 * 2^4)
           = round(8)
           = 8

產生的位元模式:

0000.1000

要將固定小數點數值轉換回實數:

RealValue = FixedPoint / 2^F

範例:

RealValue = 8 / 2^4
          = 8 / 16
          = 0.5

運算子與設計規則#

運算子僅處理整數位元模式。在固定小數點算術中,虛擬小數點的位置由 Q 格式決定,且必須在整個設計過程中加以追蹤。

以下運算子常用於調整縮放比例並維持預期的 Q 格式:

  • 當 ShiftLeft 進行明確的生命週期管理即呼叫 ShiftRight 這些運算子會將輸入位元模式向左或向右移位,移位位元數可設定。向左移位會將數值乘以 2^Shift;向右移位則會將數值除以 2^Shift。這些運算子通常用於算術運算之後,以恢復所需的 Q 格式。
  • SCALE 或 ShiftLeft: 請使用這些運算子來取代 MULT 當將一個數值乘以二的某個常數次冪時。這兩種方法執行相同的縮放運算,但通常所需的 FPGA 資源較少。
  • 當 MULT 此運算子會將兩個輸入值相乘。輸出位元寬度等於兩個輸入位元寬度的總和。在固定小數點運算中,結果中的小數位元數也是兩個操作數小數位元數的總和。

範例#

將一個 Q4.4 值乘以另一個 Q4.4 值,會得到一個 Q8.8 的結果:

Q4.4 * Q4.4 -> Q8.8

此結果雖能提供更高的精確度,但可能需要後續的 ShiftRight 若設計預期為 Q4.4 值,則需進行運算或位寬縮減。

某些運算子會假設特定的固定點格式。例如,三角函數運算子,如 SIN, COS, TAN,且其反函數的輸入與輸出均需符合預先定義的分數位元數。

在將連結與此類運算子連接之前,請先參閱《運算子參考》中的「算術函式庫」,確認所需的格式。

設計指引

請在每個階段記錄 Q 格式。進行乘法或除法運算後,請使用 ShiftRight 或視需要調整位元寬度,以恢復預期的格式。

在模擬中顯示定點數值#

您可以在VisualApplets 中使用模擬功能,於建構小程式之前,驗證固定點數值是否如預期般被解讀、縮放並在設計中傳遞。在「模擬探針檢視器」中,連結值仍為整數,但您可以透過設定小數位元、選擇有符號/無符號十進位,以及選擇性地套用縮放係數,將其顯示為固定點數值。這僅影響顯示效果,不會影響硬體。若要透過VisualApplets 中的模擬功能檢查固定點數值:

  1. 在處理管線的起始處新增一個模擬來源。
  2. 在操作員的輸出鏈路上新增一個模擬探針。
  3. 透過「分析」→「開始模擬」來啟動模擬。
  4. 開啟「模擬探針檢視器」,以檢視您在步驟 2 中新增的探針。
  5. 在「模擬探針檢視器」中,請選擇有符號或無符號十進位顯示。
  6. 請將小數位數設定為與您的 Q 格式相符。
  7. 可選擇設定單位轉換的縮放係數,例如將弧度轉換為度。

因此,您可以看到「模擬探針」是如何將小數位納入考量的:

模擬探針:顯示已將分數位元納入考量的結果。

有關VisualApplets 中模擬功能的更多資訊,請參閱《使用者手冊》中的「模擬」章節。

使用 SelectBitField 擷取位元欄位#

當 SelectBitField 此運算子會從輸入值中擷取一組連續的位元,並將其複製到輸出。當您只需要較大資料字中的特定部分時,請使用此運算子。

請依照以下方式設定操作員:

  • 設定輸出 Bit Width 在輸出鏈路上。這決定了要萃取多少位元。
  • 將相機中的 BitOffset 參數。此參數指定要複製至輸出的選定欄位中最低有效位元 (LSB) 的位置。所選定的位元將成為輸出值的第 0 位元(即最低有效位元)。

對於灰階影像, BitOffset 必須在以下範圍內:

0 ... Input Bit Width - Output Bit Width

如果輸入採用有符號算術,則提取的位元始終會以無符號值的形式輸出。

SelectBitField:輸入與輸出連結「Bit Width 」及模組屬性「BitOffset」的依賴關係

為下游軟體擴展Bit Width #

許多相機產生的像素資料,其位元寬度通常為每像素 10 或 12 位元。然而,影像處理軟體和影像檔案格式通常採用 8、16 或 32 位元等標準資料位元寬度。

因此,在將相機資料傳輸至主機電腦之前,通常會先將其轉換為 16 位元像素。您可以透過以下方式進行此操作:

使用 ConvertPixelFormat#

若要擴大位寬,您可以插入一個 ConvertPixelFormat 位於影像來源或緩衝區與 DmaToPC.

插入 ConvertPixelFormat 操作員,請開啟輸出連結的屬性並設定 Bit Width 設為 16.

舉例來說,在將 9 位元畫素資料轉換為 16 位元時,該運算子會將每個畫素值向左移位 7 位元,並在新產生的最低有效位元位置填入零。此舉在將資料轉換為 16 位元格式的同時,也保留了相對的亮度範圍。

使用 ConvertPixelFormat 運算子擴展Bit Width

使用 ShiftLeft#

此外,您也可以插入一個 ShiftLeft 運算子,並設定 Shift 將參數設為 7。

向左移位 7 位元所產生的縮放效果,與將 9 位元數值轉換為 16 位元數值的效果相同:

9-bit value << 7

輸出鏈路隨後傳輸 16 位元的像素值。

運用 ShiftLeft 運算子擴展Bit Width

使用 CastBitWidth#

若要增加位寬而不改變數值,請插入一個 CastBitWidth 運算子。若下游軟體需要更寬的位元寬度,但又不希望對像素值進行縮放,請選擇此選項。

若要使用 CastBitWidth 運算子,變更該的輸出鏈路上的位元寬度 CastBitWidth 運算子:

使用 CastBitWidth 運算子擴展Bit Width

有別於 ConvertPixelFormat 或 ShiftLeft, CastBitWidth 不會位移像素資料。相反地,它會在保留原始數值的同時,追加高位元。

使用 DRC 驗證您的設計#

在變更位寬或插入算術運算子後,請執行「分析」→「設計規則檢查第 1 級」。第 1 級檢查會將位寬不匹配及參數衝突的狀況記錄於DRC 日誌中,並在設計窗格中將受影響的模組與連結標示出來。

執行 設計規則檢查第 2 級 在建置之前。第 2 級會估算 FPGA 資源的使用量。寬格式的中間結果以及運算子,例如 MULT 進行明確的生命週期管理即呼叫 DIV 增加資源消耗。

請一併閱讀 DRC 日誌,並參閱其中標示的模組與連結。如需完整的作業流程,請參閱「從空白設計到可執行的 Applet」教學主題。

關鍵術語

Basler 建議在處理位寬時採用以下做法:

  • 檢查已傳播的 Bit Width 在每個算術運算子之後的下游連結上。
  • 在將寬度縮窄之前,請先裁剪數值。
  • 應盡早為主機軟體規劃位元寬度的變更,例如在 DMA 之前將每像素設定為 16 位元。
  • 使用 ShiftLeft 進行明確的生命週期管理即呼叫 ShiftRight 用於二的冪縮放,而非 MULT 進行明確的生命週期管理即呼叫 DIV 在可能的情況下。
  • 當參數值無法保留時,請參閱《運算子參考手冊》。