• 沒有找到結果。

第三章 FBP 演算法嵌入式系統實作

3.4 FBP 元件實作說明

接下來我們要介紹的是實作的核心部分,也就是 user_logic 模組實作,這個 部分主要是由五大部分所組成,如圖 3-13 所示,每個部分各有其不同的作用且 意義分述如下:

z IDLE:為剛開始的初始狀態,且之後當程式執行至此狀態時則不做任何事,

等待新的命令執行。

z LOAD_IN:主要的功能是藉由 32 個 64bit 的暫存器將軟體端的資料儲存到 由 Signal-Port Block Memory 這個 IP 所合成的 Block RAM 中,以便在硬體 上作運算。

z FILTER:這個狀態所做的工作包含將讀入的資料作 fft、filter、以及 ifft,完 成後的資料及可拿來做反投影(back projection)。

z LOAD_OUT:主要的功能是藉由 32 個 64bit 的暫存器將硬體端的資料搬出 到軟體端。

z BP:這部分主要的工作就是將狀態 FILTER 完成後的資料在硬體裡作反投影 的工作。

IDLE

LOAD_IN

FILTER

BP LOAD_OUT

圖 3-13 user_logic 模組狀態圖

繼續我們在針對狀態圖中的 FILTER 以及 BP 兩個比較重要的部分作一個比 較詳細的介紹:

圖 3-14 是 FILTER 狀態的一個詳細說明圖,剛開始由於資料尚存在 Block RAM 中,因此我們需要有一個狀態 fft_load 將這些資料一筆筆 load 至 Fast Fourier Transform v3.1 IP 邏輯合成的電路中,之後狀態 fft_transform 開始作傅立葉運算,

接下來進入狀態 filter_operate 將傅立葉運算完的值乘與濾波器|ω|,待整個運算

完成後再利用 fft_unload 將運算完結果寫回 Block RAM 中,之所以要先寫回 Block RAM 而不直接繼續做反傅立葉運算的原因是因為當初我們在 IP 的架構設定上是 採用 Radix-4, Burst I/O,主要理由是為了減少硬體資源的消耗。接下來同樣的做 法利用 ifft_load 狀態將資料 load 進 IP 中,狀態 ifft_transform 作反傅立葉運算,

最後 ifft_unload 狀態下將運算完成的資料寫回 Block RAM 中以待後續處理。

而由於我們沒辦法將所有經 fft、filter、ifft 處理過後的資料全部存放在 Block RAM 中,因此在這種情況下我們會將狀態跳至 LOAD_OUT,將處理過後的資料 寫回暫存器,由軟體讀回資料。

完成 FILTER 工作後,接下來就是要做反投影,而由於我們是採分塊式來實 作,因此必須先於軟體端計算出每一個區塊其對應的 sub_sinogram 區段以便拿來 作反投影的動作。以一個 4x4 大小的區塊為例,請參考圖 3-15,依照我們的演 算法會在對應的 sub_sinogram 區段上由 block_sino_start 至 block_sino_end 取出七 個要反投回去的點,暫時稱之 filtered_real(i , j),其中 i 指第幾次投影而 j 是 sinogram 上的 index,另外還需求出該點所在之座標 x_coordinate、y_coordinate。

圖 3-15 求出 sub_sinogram 及反投影點示意圖

當所要的資料都求出後,我們就開始編碼動作,將 x_coordinate、y_coordinate 以及 filtered_real(i , j)以 bit 形式編入 Xuint64 此種資料型態之中,Xuint64 可分成 upper 以及 lower 兩部分且分別由兩組 Xuint32 所組成,我們將 filtered_real(i , j) 置於 Xuint64 中 upper 的部分,而將 x_coordinate、y_coordinates 合併置於 Xuint64 中 lower 的部分,每筆資料之所以要佔這麼多 bits 的原因是因為在硬體中並不支 援浮點數的運算,因此我們必須把資料乘以 2 的 10 次方,以盡量保持資料的正 確性。圖 3-16 就是編碼的一個示意圖,完成後靠 32 組每組 64bit 的暫存器將 Xuint64 此種資料型態的資料送進硬體端等待重建,如此一來可以一次將三種資 料傳送至硬體而不需要每種資料各傳一次,可以減少資料傳送所耗費的時間,此 外在作重建的過程中我們還需要知道每個角度的 sin、cos 值,為避免浪費硬體的

資源所以我們不在硬體端使用查表方式來取得,而是在軟體端先取得其值後,同 樣使用暫存器將資料送至硬體。

圖 3-16 編碼示意圖

當資料被送達硬體端後,狀態 block_bp_start 就會被啟動並送出一個觸發訊 號,同時啟動狀態 even_bp_start 以及 odd_bp_start,如圖 3-17 所示。其中 even 及 odd 是指對於要反投影回去的七個點分成奇數及偶數,然後各自做反投影的動 作,所以這裡我們需要兩份相同的系統資源,一旦接受到由 block_bp_start 發送 出的觸發訊號就各自進入 decode 狀態,開始解碼動作。而在硬體中考慮到資料 正確性及盡量節省資源的原則,我們採用三組 std_logic_vector(0 to 15)來分別儲 存由軟體端傳過來的 x_coordinate、y_coordinates 以及 filtered_real(i , j),在硬體 端取出這些值後,解碼動作就算完成了。

圖 3-17 BP 狀態內部狀態圖

decode operate odd_bp_start

decode operate even_bp_start

IDLE

block_bp_start block_bp_end

接下來便進入 operate 狀態,而在這之前我們先由圖 3-18 簡單介紹一下硬體 中的 block 是如何重建。以單個點的反投影為例,在完成解碼後我們可以得到 sub_sinogram_cen 的 x_coordinate、y_coordinates 以及 filtered_real(i , j),之後利 用加上一個Δk×sinθ 及Δk×cosθ 的偏移量得到下一個位置,如果其範圍仍在(0,0) 與(3,3)之間,則我們就取新的 x_coordinate、y_coordinate 之整數座標,並將 filtered_real(i , j)累加至該新座標上。

加上第一次 sin 及 cos 偏移量後的位置

Sub_sinogram_cen

圖 3-18 block 重建示意圖

圖 3-19 說明了硬體中 operate 狀態的整個流程,為了減少 I/O 次數,在重建過程 中我們會一次將此 block 所有角度的投影都做完,也就是從 0 度開始做到 127 度,

並且在硬體中累加,而不是做完一個角度的投影就將結果回傳至軟體。一旦 even 或 odd 某一邊完成反投影的工作就會送出一個完成訊號給 block_bp_end,等到兩 邊都完成重建後我們就將兩者結果相加,並將最後結果回傳至軟體,完成單個 block 之重建。因此每當硬體寫回結果,就是完成了單個 block 整個的重建工作,

如此依序做完所有 blocks,就可以得到整張影像重建後的結果。

Decode

將 x_coordinate、y_coordinate 量化成整數座標,

x_int_coor、y_int_coor

依照 x_int_coor、y_int_coor 判斷該點是否要加上該次反 投影的 filtered_real(i , j)值,是 則累加,反之則不做任何動作

第四章 結果討論與未來展望

相關文件