FPGA series # gamma模塊總結文檔

雖說回頭再看的時候這東西很基礎,但也是一開始花了些時間一點點啃下來的。勿忘初心。

一、引言

1.編寫目的:

總結gamma矯正模塊的總體設計、詳細設計及仿真測試、後期優化。

2.項目背景:

編寫gamma矯正模塊。

3.定 義:

  1. gamma校正: 大多數CRT顯示器的變換函數產生的亮度值正比於信號幅度的某種能量(稱爲gamma)。因此高亮度的範圍被擴展了,而低亮度的範圍被壓縮了。在發射之前對視頻信號進行gamma校準,顯示器的亮度輸出就大體上是線性的了,並且發射過程中產生的噪聲也會受到抑制。
    目的: 爲圖像進行gamma編碼的目的是用來對人類視覺的特性進行補償,從而根據人類對光線或黑白的感知,最大化地利用表示黑白的數據位或帶寬。
    原理: 歸一化、預補償、反歸一化
    算法: 假設圖像中有一個像素A,值是150,那麼對這個像素進行校正須執行如下步驟。
    歸一化: 將像素值轉換爲 0~1 之間的實數。 算法如下: ( i + 0. 5)/256 。對於像素 A 而言 ,其對應的歸一化值爲 0. 587891。
    預補償: 根據公式L_in=〖L_org〗^(1/gamma),求出像素歸一化後的數據以 1/gamma 爲指數的對應值。若 gamma 值爲 2. 2,則 1/gamma 爲 0. 45454,對歸一化後的 A 值進行預補償的結果就 是 0. 587891^0. 454545 = 0.785479。
    反歸一化: 將經過預補償的實數值反變換爲 0 ~ 255 之間的整數值。具體算法爲: f*256 - 0. 5 。續前例,將 A 的預補償結果0.785479 代入上式,得到 A 預補償後對應的像素值爲 201 ,這個 201 就是最後送 入顯示器的數據。
  2. 圖像數據 : 用數值表示的各像素的灰度值的集合。
  3. 灰 度 值 : 指黑白圖像中點的顏色深度,範圍一般從0到255,白色爲255,黑色爲0,故 黑白圖片也稱爲灰度圖像。灰度也可認爲是亮度,簡單的說就是色彩的深淺程 度,R、G、B值均相等。
  4. 參考資料: [1] PG058 Block Memory Generator v8.4 LogiCORE IP Product Guide.
         [2] UG908 Vivado Design Suite User Guide Programming and Debugging.
         [3] PG021 AXI DMA v7.1 LogiCORE IP Product Guide.

二、總體設計

1.需求概述:

從BRAM數據源讀取圖像數據,進行gamma矯正,然後存入RAM中。

2.模塊結構:

0
  後期將RAM2接口改爲AXIS型,只取RAM2_gamma模塊,將其放入整個工程中。修改後的模塊結構應爲:
(接口對應工程中的前後兩個模塊分別爲:alinx_ov5640_0,System_i)
1

3.Schematic:

2

4.模塊描述

  • Top
    功能:頂層模塊,調用下面三個模塊,加一個ila的IP核以實時仿真時探取信號
    輸入:clk,rst

  • Module1
    功能:存放圖像數據源,導入.coe文件
    輸入:clk,rst_b 輸出:dout_b

  • Module2
    功能:存放matlab計算結果,調取像素值相對應的gamma矯正結果
    輸入:clk,rst_g,din_g 輸出:dout_g

  • Module3
    功能:存放矯正後的數據
    輸入:clk,rst_g,dina_a 輸出:doutb_a

  • 後期將Module2模塊改爲AXIS接口,則該模塊應爲:
    RAM_gamma
    功能:存放matlab計算結果,調取像素值相對應的gamma矯正結果
    輸入:clk,resetn, 輸出:
    s_axis_gamma_rdata, m_axis_gamma_tdata,
    s_axis_gamma_rvalid, m_axis_gamma_tvalid,
    m_axis_gamma_rready, s_axis_gamma_tready,
    s_axis_gamma_rlast, m_axis_gamma_tlast,
    s_axis_gamma_ruser, m_axis_gamma_tuser,
    s_axis_gamma_rkeep m_axis_gamma_tkeep

三、詳細設計

1.代碼語言:

verilogHDL,c語言

2.運行環境:

Vivado 2017.4,modelsim,ALINX黑金AX7020開發板,matlab 2014

3.各模塊設計:

3

  • RAM1:存放圖像數據;
  • RAM2:存放0~255之間整數gamma矯正的結果;
  • RAM3:存放圖像數據gamma矯正的結果
    ① 數據源位寬:RAM1輸入輸出數據位寬:8位; RAM2輸入輸出數據位寬:8位;RAM3輸入輸出數據位寬:8位;
    ② 數據源深度:RAM1深度:128128(圖像數據源:128124);RAM2深度:256;RAM3深度:2^14
    ③ 時鐘同步
    ④ 圖像矩陣作爲數據源讀入順序:從上到下
      後期將RAM2模塊改爲AXIS接口直接加到工程裏,端口爲:data,keep,valid,ready,last,user。參考datasheet,如圖:
    4
    由上圖分析,
  • aclk爲時鐘線,所有信號都在aclk上升沿被採樣;
  • data爲數據線,主機發送,從機接收。
  • keep爲主機數據有效指示,爲高代表對應的字節爲有效字節,否則表示發送的爲空字節。
  • valid爲主機數據同步線,爲高表示主機準備好發送數據;
  • ready爲從機數據同步線,爲高表示從機準備好接收數據;這兩根線完成了主機與從機的握手信號,一旦二者都變高有效,數據傳輸開始。
  • last爲主機最後一個字指示,下一clk數據將無效,TVALID將變低。
    另,user爲valid和ready同時爲高時才爲有效數據。
      考慮到RAM2模塊的輸入輸出爲8位,模塊alinx_ov5640_0和System_i輸入輸出爲16位,將輸入數據取高8位爲0,低8位輸入。輸出時,將8位的輸出數據放在最終輸出數據的低8位,其高八位置0。這裏的keep始終爲2’b11。分析得具體接口連接如圖:
    5

4.實現方案:

  • 在matlab中計算、對比:計算0~255之間所有整數的gamma矯正結果。
  • 將仿真數的結果放入matlab,恢復成圖像,輸出處理後的圖像。
  • 在modelsim中仿真:ila中探針探取想要看的結果。
  • 在FPGA中實現:將matlab中讀出的圖像數據存入RAM1作爲數據源,其輸出與RAM2中的gamma矯正結果相匹配,將匹配後的值存入RAM3。

5.步 驟:

① 從matlab中提取圖像的一維數組元素存入.COE文檔;

src_path = 'rice.jpg';
I = imread(src_path);
x = I(:,:,1);
my_write(x,'E:\practice\gamma\RAM1.COE','%0.2x\n');

② 將文檔中的數據作爲數據源,存入RAM1中,RAM1選擇single port ROM,導入.COE文件;
6
7
③ 在matlab上計算0~255之間所有整數的gamma矯正結果,並存入RAM2;

i  = [0:1:255];							//生成0~255的整數數組
A = (i+0.5)/256;						//歸一化
f = A.^(1/2.2);							//預補償
s = f*256 - 0.5;						//反歸一化
r=round(s);								//四捨五入取整
my_write(r,'E:\gamma.dat','%0.2x\n')	//數據讀出到.dat文檔中

④ 將每個時鐘週期從RAM1輸出的數據作爲地址在RAM2中查找計算結果;
⑤ RAM2輸出的值存入到RAM3中,RAM3可選選擇Block Memory Generator中的Simple Dual Port RAM。
8
⑥ 在testbench中導出RAM3中的數據:

//宏定義
define stor_file "E:/practice/gamma/out.dat"
//變量聲明
integer fid1;
initial begin
//打開輸出數據文件 
fid1 = $fopen(`stor_file,"w");
end
//-----------導出輸出數據----------
always@(posedge clk) begin       
$fdisplay(fid1,"%x",doutb_a[7:0]);
end

⑦ 在top文件中加入IP核ila,探取需要知道的信號波形。這裏舉例探取dout_b和doutb_a信號。 9
10

ila_0 ila_0(
  					.clk(clk),	                	 	
					.probe0(dout_b),
					.probe1(doutb_a)
					);

⑧ 將top模塊例化,加入到整個工程中去,clk和resetn分別對應工程中的FCLK_CLK1和FCLK- CLK1RESETN。在綜合佈線後生成bit文件,將bit文件名改爲fpga.bit,替換板子上sd卡里 的bit文件。在vivado中open target,連接開發板,進行時序仿真。
⑨ 在matlab裏對比分析matlab矯正的結果和verilog矯正的結果是否一致。
 matlab代碼:

src_path = 'rice.jpg';
gamma = 2.2 ;
N = 256;
S = 0.5;
%讀取數據
I = imread(src_path);
%gamma矯正
i = double(I);
A = (i + 0.5) / 256;
F = A.^(1/gamma);
B = F*N - S;
b = uint8(B);
%畫圖分析
figure;
subplot(1, 2, 1); 
imshow(I, []);
title('原圖');
subplot(1, 2, 2); 
imshow(b, []);
title('matlab處理後');

將verilog矯正後的數據提取出來,輸出圖像:

fid = fopen('out.dat');
a = textscan(fid,'%s');             %讀取矯正後的數據
b = a{1};                           %textscan生成的是cell型的數組
c = cell2mat(b);                    %cell轉換爲矩陣
d = hex2dec(c);                     %轉爲十進制
s = cat(3,d,d,d);
e = reshape(s,124,128,3);           %重組回原圖像的像素值
f = uint8(e);                       %強制轉換爲uint8的格式
imshow(f);                          %顯示圖像
title('verilog處理後');

⑩ 後期將RAM2改爲AXIS型接口,單獨作爲一個模塊整合進工程代碼中。

四、測試仿真

1.測試要點:

① 將RAM3存儲的處理後的數據與matlab處理後的數據對比
② 將上兩組數據轉化爲圖像,進行對比

2.測試結果:

① matlab correction:
11Verilog correction:
12
② matlab:
13
Verilog:
14

3.仿 真:

modelsim仿真,ila的探針探取的結果與之前仿真結果對比

4.仿真結果:

  • ila分別採樣三個模塊的輸出數據
    15
    16
  • ila採樣的module1和module3的數據,在隨機抓取的樣值中看到空出來的數據00和0f 17
  • 這裏的00分爲兩段,前一段是RAM深度爲16384,但圖像數據爲128*124=15872,空餘的深度值 18
  • 後一段的00是延時 19
    將RAM2改爲AXIS型接口,單獨作爲一個模塊整合進工程代碼中之後的仿真結果。
  • ila探取輸入值和輸出值
    20
    21
    23
    24

不足:仿真中波形爲隨機抓取,可以考慮將觸發改爲從地址0開始。

後期將RAM2接口改爲AXIS型,只取RAM2_gamma模塊,將其放入整個工程中。修改後的模塊結構應爲:
(接口對應工程中的前後兩個模塊分別爲:alinx_ov5640_0,System_i)

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