色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何在FPGA中正確處理浮點數運算

FPGA設計論壇 ? 來源:FPGA設計論壇 ? 作者:FPGA設計論壇 ? 2022-03-18 11:03 ? 次閱讀

使用插值算法實現圖像縮放是數字圖像處理算法中經常遇到的問題。我們經常會將某種尺寸的圖像轉換為其他尺寸的圖像,如放大或者縮小圖像。由于在縮放的過程中會遇到浮點數,如何在FPGA中正確的處理浮點數運算是在FPGA中實現圖像縮放的關鍵。

一、插值算法原理

在圖像的縮放處理過程中,經常會用到插值算法,常見的插值算法包括最鄰近插值,雙線性插值,雙三次線性插值,蘭索斯插值等方法。其中,雙線性插值由于折中的插值效果和實現復雜度,運用較為廣泛。本文中僅介紹最臨近插值,重點討論如何在FPGA平臺上使用雙線性插值實現圖像的縮放。

1.1 最臨近插值---------最臨近插值介紹

講理論不如舉例子來的快,所以為了更好更快的理解最臨近插值,我們通過舉個簡單的例子來解釋最臨近插值是個什么神奇的東西。假如有一個3*3矩陣(一幅圖像其實就是矩陣),如下,我們把這個圖像叫做原圖(source image):

66 28 128

25 88 200

36 68 120

在矩陣中,坐標(x,y)是這樣確定的,矩陣的左上角的頂點為原點,從左到右為x軸,從上到下為y軸,如下所示:

24ef1ada-a667-11ec-952b-dac502259ad0.png

圖1 圖像中坐標確定方式

假設我們想把這個3*3的原圖擴大成4*4(我們把這個4*4的圖像叫做目的圖像destination image)我們該如何做呢?首先當然是先把4*4的矩陣畫出來,如下所示:

????

? ???

????

????

矩陣畫出來后,接下來就要像未知數里填充像素點了。要填入的值如何計算呢,通過如下公式進行計算:

24fed5f6-a667-11ec-952b-dac502259ad0.png

首先我們先來填充目的圖像 (0,0),套用上述公式可得到對應原圖像的坐標點,srcX =0,srcY= 0;找到原圖像中對應的坐標點的像素值,將該像素填充到目的圖像中,如下

66 ???

????

????

接下來填充目的圖像(1,0),仍然套用公式,srcX = 3/4,srcY = 0,結果發現得到的結果居然有小數,由于計算機中的像素點已經是最小單位,像素的坐標都是整數,沒有小數。這是只需要按照四舍五入的思想將小數坐標轉換為整數坐標即可.所以(3/4,0) ≈ (1,0),把原圖像中(1,0)點的像素值填入目的圖像(1,0)坐標處,得到如下結果:

66 28 ??

????

????

接下來重復上述過程,就可得到放大后的目的圖像,如下:

66 28 128 128

25 88 200 200

36 68 120 120

36 68 120 120

這種放大圖像的方法叫做最臨近插值算法,這是一種最基本最簡單的圖像縮放算法,該方法縮放后的圖像會出現失真現象。

1.2 雙線性插值算法

雙線性插值算法是一種比較好的縮放算法,它充分利用源圖中虛擬點四周的四個像素點來共同決定目標圖形中的一個像素值,因此縮放效果要比最臨近插值算法好的多。

雙線性插值算法的描述如下:

對于目的圖像中的某點坐標,通過乘以縮放倍數(srcwidth/dstwidth、srcheight/dstheight)得到一個浮點坐標(i+u,j+v)(其中i,j均為浮點坐標的整數部分;u,v為浮點坐標的小數部分),則這個浮點坐標(i+u,j+v)處的像素值f(i+u,j+v)可以由原圖像中的坐標點(i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所對應的四個像素值來共同決定,即

2515c7a2-a667-11ec-952b-dac502259ad0.png

如1.1計算的目的像素坐標(1,0)對應源圖像的坐標為(3/4,0),即 i = 0,u = 0.75;j = 0,v = 0;即目的圖像(1,0)處的像素值由源圖像中(0,0)、(1,0)、(0,1)(1,1)四個坐標點對應的像素值來確定,代入上述公式即可計算出(3/4,0)處的像素值。

看了上述內容應該對最臨近插值算法和雙線性插值算法有一定的了解,其基本原理應該已經掌握。

在網上刷博客發現有好多大佬講解了雙線性插值算法的優化(雙線性插值算法總結),發現優化以后縮放效果更好一些,優化的具體細節就不再講解,具體優化過程就是使用

252cb0a2-a667-11ec-952b-dac502259ad0.png

寫到這里雙線性插值算法的基本原理及優化方式已經基本講述完畢,那么,如何使用FPGA來實現雙線性插值呢?接下來我們進行分析如何使用FPGA來實現雙線性插值。

二、雙線性插值的FPGA實現遇到的問題及解決方案

通過以上分析,我們會發現使用FPGA實現雙線性插值有以下難點:

如何處理算法中出現的小數;

如何同時求出相鄰的四個點的坐標以及系數;

如何使用這四個坐標同時輸出相鄰的四個像素值;

接下來我們依次解決上述問題

2.1 如何處理算法中出現的小數

FPGA處理浮點數一般都是將浮點數轉化為定點數進行處理,我們在求srcX、srcY也按照此思想。由于FPGA中沒法進行小數表示,因此我們將srcX、srcY放大一定倍數變成整數,這個整數的高n位表示坐標點的整數部分(i或j),低m位表示小數部分(u或者v)。如我們要將30*30的圖像放大成64*64即srcwidth = srcheight = 30,dstwidth = dstheight =64(接下來工程實現也按照此例子來實現)。

254257cc-a667-11ec-952b-dac502259ad0.png

位寬為16位。由于放大了128倍,所以srcX[6:0]、srcY[6:0]的低7位表示小數部分,即u = srcX[6:0],v=srcY[6:0];

其余高位部分表示整數部分,即i = srcX[15:7],j = srcY[15:7]。這樣就可以解決算法中出現的小數問題。

2.2如何同時求出相鄰的四個點的坐標以及系數

由1.1可知,我們可以求出第一個坐標點(i,j) = (srcX[15:7],srcY[15:7]),那么如何求出相鄰其它三個點的坐標呢?接下來需要求出其余三點(i+1,j)、(i,j+1)、(i+1,j+1)的坐標,

(i+1,j) = (srcX[15:7] + 'd1,srcY[15:7]);

(i,j+1) = (srcX[15:7] ,srcY[15:7] * srcwidth);

(i+1,j+1) = (srcX[15:7] + 'd1 ,srcY[15:7] * srcwidth);

通過以上方式便可以很容易的求出四個點的坐標。接下來就要考慮如何使用這四個坐標同時讀取四個對應的像素值。

同時我們定義四個位寬為8位的系數變量coefficient1[7:0]、coefficient2[7:0]、coefficient3[7:0]、coefficient4[7:0],通過

coefficient1[7:0] = ‘d128 - coefficient2;(由于系數放大了128倍,所以是128-系數2,對應1-u)

coefficient2[7:0] = {1'b0,u} = {1'b0,srcX[6:0]};

coefficient3[7:0] = ‘d128 - coefficient4;(由于系數放大了128倍,所以是128-系數4,對應1-v)

coefficient4[7:0] = {1'b0,v} = {1'b0,srcY[6:0]};

為什么定義的系數變量為8位而不是7位,這是因為系數變量的最大值為’d128,8位位寬才能表示‘d128。

接下來使用上述求出的四個坐標求出對應的坐標的像素值,再套用公式

25576a9a-a667-11ec-952b-dac502259ad0.png

即可求出目的圖像對應位置放大后的像素值。

通過以上分析,可以將公式變形為如下形式,求出對應點的像素值后直接使用以下公式即可:

256bb310-a667-11ec-952b-dac502259ad0.png

求得該像素值之后還需要將該像素值除以128*128才是所得的實際結果。

2.3 如何使用這四個坐標同時輸出相鄰的四個像素值

通過2.2分析可以同時求出四個像素點的坐標,但是如何通過這四個坐標同時求出對應的像素值呢?由于待縮放的數據是先緩存進RAM的,如果待縮放的圖像數據僅僅緩存在一個RAM里,是不可能通過四個像素點的坐標同時訪問這個RAM,即不可能同時求出對應的四個像素點的值。所以,可以通過犧牲面積換取速度的方式,即將RAM復制4次,每個RAM都緩存整個待縮放的圖像數據,這樣四個像素點的坐標就可以通過訪問不同的RAM來同時訪問對應的四個像素值了。雖然犧牲了FPGA內部的存儲資源,但是提升了雙線性插值算法的速度。

三 、雙線性插值的FPGA實現

通過第二節內容的分析可知,使用FPGA實現雙線性插值主要包含以下三個模塊:生成目的圖像對應原圖像坐標和系數模塊、待處理圖像緩存模塊、雙線性插值運算單元模塊。其數據流向圖如下圖所示:

257eb168-a667-11ec-952b-dac502259ad0.png

圖2 FPGA實現雙線性插值數據流向圖

圖2中虛框部分是圖像裁剪模塊,這里不討論圖像裁剪功能的實現,僅僅討論圖像縮放功能的實現。

整個實現的過程描述如下:

上位機將待縮放的圖像數據送進待處理圖像緩存模塊,該模塊將待處理的數據復制四份

待1中數據緩存完畢,開始生成目的圖像對應原圖像坐標和系數;

將生成的坐標送給待處理圖像緩存模塊進行數據的訪問,將讀取的數據送給雙線性插值運算單元;

將生成的系數送給雙線性插值運算單元,與相應的像素值進行數學運算,實現雙線性插值功能。

實現雙線性插值功能的代碼如下所示:

頂層模塊:

module top(input clk,

output [7:0]doutb,

output de_o,

output v_sync,

output h_sync

);

parameter [7:0]src_width = 'd30;

wire [7:0]coordinate_x;

wire [7:0]coordinate_y;

wire start;

wire en_b;

//

wire [7:0]coefficient1;

wire [7:0]coefficient2;

wire [7:0]coefficient3;

wire [7:0]coefficient4;

wire [7:0]doutbx;

wire [7:0]doutbx1;

wire [7:0]doutby;

wire [7:0]doutby1;

// Instantiate the module

sourceimage_virtualcoordinate coordinate (

.clk(clk),

.src_width(src_width),

.start(start),

.coordinate_x(coordinate_x),

.coordinate_y(coordinate_y),

.coefficient1(coefficient1),

.coefficient2(coefficient2),

.coefficient3(coefficient3),

.coefficient4(coefficient4),

.en(en_b)

);

//

wire [7:0]dina;

wire valid_zsc;

// Instantiate the module

self_generate self_generate (

.clk(clk),

.data_o(dina),

.valid_zsc(valid_zsc)

);

// Instantiate the module

mem_control mem_control (

.clk_wr(clk),

.clk_rd(clk),

.coordinate_x(coordinate_x), /

.coordinate_y(coordinate_y),

.din_a(dina), /

.en_a(valid_zsc), ///

.src_width(src_width), //

.en_b(en_b), ///

.doutbx(doutbx),

.doutbx1(doutbx1),

.doutby(doutby),

.doutby1(doutby1),

.start(start)

);

///

wire [7:0] data_o;

wire en_o;

// Instantiate the module

arithmetic_unit arithmetic_unit (

.clk(clk),

.coefficient1(coefficient1),

.coefficient2(coefficient2),

.coefficient3(coefficient3),

.coefficient4(coefficient4),

.en_b(en_b),

.doutbx(doutbx),

.doutbx1(doutbx1),

.doutby(doutby),

.doutby1(doutby1),

.data_o(data_o),

.en_o(en_o)

);

wire de;

wire start_en;

// Instantiate the module

mem_64multi_64 mem_64multi_64 (

.clk(clk),

.dina(data_o),

.ena(en_o),

.enb(enb),

.start_en(start_en),

.doutb(doutb)

);

// Instantiate the module

vesa_out vesa_out (

.clk(clk),

.start_en(start_en),

.v_sync(v_sync),

.h_sync(h_sync),

.de(enb),

.de_o(de_o)

);

endmodule

生成對應的坐標和系數模塊:

//該模塊是用來計算源圖像的虛擬坐標,由于源圖像和目的圖像都是正方形,所以只考慮一個縮放倍數即可

//

module sourceimage_virtualcoordinate(input clk,

input [7:0]src_width,/src_width = src_height

input [5:0]dest_width,/dest_width = dest_height = 'd64

input start,///數據緩存滿了以后才可以進行計算

output [7:0]coordinate_x,

output [7:0]coordinate_y,

output [7:0]coefficient1,

output [7:0]coefficient2,

output [7:0]coefficient3,

output [7:0]coefficient4,

output reg en = 'd0

);

/高電平有效rst

reg [1:0]cnt = 'd0;

always @(posedge clk)

if(cnt == 'd3)

cnt <= 'd3;

else

cnt <= cnt + 'd1;

reg rst = 'd1;

always @(posedge clk)

if(cnt == 'd3)

rst <= 'd0;

else

rst <= 'd1;

//

localparam [1:0]IDLE = 2'b01;

localparam [1:0]START = 2'b10;

/

reg[1:0]next_state = 'd0;

reg[1:0]current_state = 'd0;

always @(posedge clk)

if(rst)高電平復位

current_state <= IDLE;

else

current_state <= next_state;

//

reg finish = 'd0;

always @(*)

case(current_state)

IDLE:begin

if(start)

next_state = START;

else

next_state = IDLE;

end

START:begin

if(finish)

next_state = IDLE;

else

next_state = START;

end

default:next_state = IDLE;

endcase

//

//reg en = 'd0;//目的坐標計數器使能

always @(*)

case(current_state)

IDLE:begin

en = 'd0;

end

START:begin

en = 'd1;

end

default:en = 'd0;

endcase

///對目的圖像坐標進行計數

reg[5:0] pos_x = 'd0;/列計數

always@(posedge clk)

if(en)begin

if(pos_x == 'd63)

pos_x <= 'd0;

else

pos_x <= pos_x + 'd1;

end

else

pos_x <= pos_x;

reg[5:0] pos_y = 'd0;行計數

always @(posedge clk)

if(pos_x == 'd63)

pos_y <= pos_y + 'd1;?

else

pos_y <= pos_y;

//結束標志

always@(posedge clk)

if((pos_x == 'd62)&&(pos_y == 'd63))///是pos_x==62而不是63

finish <= 'd1;

else

finish <= 'd0;

//通過pos_x、pos_y可以計算對應源圖像位置的虛擬坐標

reg [15:0]src_x = 'd0;///高8位表示整數,低8位表示小數

reg [15:0]src_y = 'd0;///高8位表示整數,低8位表示小數

//assign src_x = ((pos_x<<1 + 'd1)*src_width - 'd64 > 'd0)?(pos_x<<1 + 'd1)*src_width - 'd64:'d64-(pos_x<<1 + 'd1)*src_width;

//assign src_y = ((pos_y<<1 + 'd1)*src_width - 'd64 > 'd0)?(pos_y<<1 + 'd1)*src_width - 'd64:'d64-(pos_y<<1 + 'd1)*src_width;

wire [7:0]pos_xq;

wire [7:0]pos_yq;

assign pos_xq = pos_x<<1;

assign pos_yq = pos_y<<1;

///

always @(posedge clk)

if(pos_x == 'd0)begin

if(src_width > 'd64)

src_x <= src_width - 'd64;

else

src_x <= 'd64 - src_width;

end

else begin

if((pos_xq + 'd1)*src_width > 'd64)

src_x <= (pos_xq + 'd1)*src_width - 'd64;

else

src_x <= 'd64 - (pos_xq + 'd1)*src_width;

end

always @(posedge clk)

if(pos_y == 'd0)begin

if(src_width > 'd64)

src_y <= src_width - 'd64;

else

src_y <= 'd64 - src_width;

end

else begin

if((pos_yq + 'd1)*src_width > 'd64)

src_y <= (pos_yq + 'd1)*src_width - 'd64;

else

src_y <= 'd64 - (pos_yq + 'd1)*src_width;

end

//生成對應坐標

//wire [6:0]coordinate_x;

//wire [6:0]coordinate_y;

assign coordinate_x = src_x[14:7];

assign coordinate_y = src_y[14:7];

//生成對應系數

//wire [7:0]coefficient1;

//wire [7:0]coefficient2;

//wire [7:0]coefficient3;

//wire [7:0]coefficient4;

assign coefficient2 = {1'b0,src_x[6:0]};

assign coefficient1 = 'd128 - coefficient2;

assign coefficient4 = {1'b0,src_y[6:0]};

assign coefficient3 = 'd128 - coefficient4;

endmodule

模擬上位機產生待縮放的數據模塊:

//模擬的輸入圖像指標是30*30@56Hz

//

module self_generate(input clk,

output reg[7:0]data_o = 'd0,

output reg valid_zsc = 'd0

);

reg [10:0] cnt_h = 'd0;

reg [10:0] cnt_v = 'd0;

always @(posedge clk)

if(cnt_h == 'd799)

cnt_h <= 'd0;

else

cnt_h <= cnt_h + 'd1;

always @(posedge clk)

if(cnt_h == 'd799)begin

if(cnt_v == 'd524)

cnt_v <= 'd0;

else

cnt_v <= cnt_v + 'd1;

end

else

cnt_v <= cnt_v;

//reg dInValid = 'd0;

wire valid_1;

assign valid_1 = (((cnt_h >='d144)&&(cnt_h <='d173))&&((cnt_v >='d35)&&(cnt_v <='d64)))?'d1:'d0;/有效數據共30個

///

always @(posedge clk)

if(valid_1)

//if((cnt_h >='d144)&&(cnt_h <='d176))

//data_o <= 'hff;

//else if((cnt_h >='d177)&&(cnt_h <='d209))

//data_o <= 'h0f;

//else if((cnt_h >='d210)&&(cnt_h <='d242))

//data_o <= 'hff;

//else if((cnt_h >='d243)&&(cnt_h <='d275))

//data_o <= 'h0f;

//else if((cnt_h >='d276)&&(cnt_h <='d308))

//data_o <= 'hff;

//else if((cnt_h >='d309)&&(cnt_h <='d341))

//data_o <= 'h0f;

//else if((cnt_h >='d342)&&(cnt_h <='d374))

//data_o <= 'hff;

//else

//data_o <= 'h0f;

data_o <= data_o + 'd1;

else

data_o <= 'd0;

always @(posedge clk)

valid_zsc <= valid_1;

endmodule

待處理圖像緩存模塊:

module mem_control(input clk_wr,

input clk_rd,

input [7:0]coordinate_x,

input [7:0]coordinate_y,

input [7:0]din_a,

input en_a,

input [7:0]src_width,

input en_b,

output [7:0]doutbx,

output [7:0]doutbx1,

output [7:0]doutby,

output [7:0]doutby1,

output reg start = 'd0

);

wire [15:0]size;

assign size = src_width*src_width - 'd1;

wire [7:0]width;

assign width = src_width - 'd1;

//把數據復制四份,通過犧牲面積換取速度

reg [15:0]address_a = 'd0;

always @(posedge clk_wr)

if(en_a)begin

if(address_a == size)

address_a <= 'd0;

else

address_a <= address_a + 'd1;

end

else

address_a <= address_a;

如果數據緩存完畢,產生start標志信號,表示可以進行數據處理

always @(posedge clk_wr)

if(address_a == size)

start <= 'd1;

else

start <= 'd0;

wire [15:0]address_bx;

wire [15:0]address_bx1;

wire [15:0]address_by;

wire [15:0]address_by1;

assign address_bx = (coordinate_x == width)?coordinate_x + coordinate_y*src_width - 'd1:coordinate_x + coordinate_y*src_width;

assign address_bx1 = (coordinate_x == width)?address_bx:address_bx + 'd1;

assign address_by = (coordinate_y==width)?address_bx:coordinate_x + (coordinate_y+'d1)*src_width;

assign address_by1 = (coordinate_x == width)?address_by:address_by + 'd1;

// Instantiate the module

ram_module ram_1 (

.clk_wr(clk_wr),

.address_a(address_a),

.en_a(en_a),

.din_a(din_a),

.clk_rd(clk_rd),

.address_b(address_bx),

.en_b(en_b),

.doutb(doutbx)

);

// Instantiate the module

ram_module ram_2 (

.clk_wr(clk_wr),

.address_a(address_a),

.en_a(en_a),

.din_a(din_a),

.clk_rd(clk_rd),

.address_b(address_bx1),

.en_b(en_b),

.doutb(doutbx1)

);

// Instantiate the module

ram_module ram_3 (

.clk_wr(clk_wr),

.address_a(address_a),

.en_a(en_a),

.din_a(din_a),

.clk_rd(clk_rd),

.address_b(address_by),

.en_b(en_b),

.doutb(doutby)

);

// Instantiate the module

ram_module ram_4 (

.clk_wr(clk_wr),

.address_a(address_a),

.en_a(en_a),

.din_a(din_a),

.clk_rd(clk_rd),

.address_b(address_by1),

.en_b(en_b),

.doutb(doutby1)

);

endmodule

雙線性插值運算單元模塊

module arithmetic_unit(input clk,

input [7:0]coefficient1,

input [7:0]coefficient2,

input [7:0]coefficient3,

input [7:0]coefficient4,

input en_b,

input [7:0]doutbx,

input [7:0]doutbx1,

input [7:0]doutby,

input [7:0]doutby1,

output reg[7:0]data_o = 'd0,

output reg en_o = 'd0

);

wire [23:0]data_1;

wire [23:0]data_2;

wire [23:0]data_3;

wire [23:0]data_4;

assign data_1 = coefficient1*coefficient3*doutbx;

/

assign data_2 = coefficient2*coefficient3*doutbx1;

/

assign data_3 = coefficient1*coefficient4*doutby;

assign data_4 = coefficient2*coefficient4*doutby1;

wire [23:0]data_a;

assign data_a = data_1 + data_2;

reg [23:0]data_aq = 'd0;

always @(posedge clk)

data_aq <= data_a;

wire [23:0]data_b;

assign data_b = data_3 + data_4;

reg [23:0]data_bq = 'd0;

always @(posedge clk)

data_bq <= data_b;

wire [23:0]data_oq;

assign data_oq = data_aq + data_bq;

always @(posedge clk)

data_o <= data_oq[21:14];

//en_b

reg en_b_q;

reg en_b_q1;

always@(posedge clk)begin

en_b_q <= en_b;

en_b_q1 <= en_b_q;

en_o <= en_b_q1;

end

endmodule

對運算后的數據進行緩存模塊:

module mem_64multi_64(input clk,

input [7:0]dina,

input ena,

input enb,

output reg start_en = 'd0,

output [7:0]doutb

);

/ram write

reg ena_q = 'd0;

always @(posedge clk)

ena_q <= ena;

reg [11:0]addra = 'd0;

always @(posedge clk)

if(ena_q)begin

if(addra == 'd4095)

addra <= 'd0;

else

addra <= addra + 'd1;

end

else

addra <= addra;

//ram read

reg [11:0]addrb = 'd0;

always @(posedge clk)

if(enb)begin

if(addrb == 'd4095)

addrb <= 'd0;

else

addrb <= addrb + 'd1;

end

else

addrb <= addrb;

//

always @(posedge clk)

if(addra == 'd4095)

start_en <= 'd1;

else

start_en <= start_en;

//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG

ram64multi64 ram64multi64 (

.clka(clk), // input clka

.ena(ena_q), // input ena

.wea(1'b1), // input [0 : 0] wea

.addra(addra), // input [11 : 0] addra

.dina(dina), // input [7 : 0] dina

.clkb(clk), // input clkb

.enb(enb), // input enb

.addrb(addrb), // input [11 : 0] addrb

.doutb(doutb) // output [7 : 0] doutb

);

endmodule

輸出顯示模塊:

module vesa_out( input clk,

input start_en,

output v_sync,

output h_sync,

output de,

output reg de_o = 'd0

);

reg [10:0] cnt_h = 'd0;

reg [10:0] cnt_v = 'd0;

always @(posedge clk)

if(start_en)begin

if(cnt_h == 'd799)

cnt_h <= 'd0;

else

cnt_h <= cnt_h + 'd1;

end

else

cnt_h <= cnt_h;

always @(posedge clk)

if(cnt_h == 'd799)begin

if(cnt_v == 'd524)

cnt_v <= 'd0;

else

cnt_v <= cnt_v + 'd1;

end

else

cnt_v <= cnt_v;

assign de = (((cnt_h >='d200)&&(cnt_h <='d263))&&((cnt_v >='d135)&&(cnt_v <='d198)))?'d1:'d0;

always @(posedge clk)

de_o <= de;

assign h_sync = (cnt_h >= 'd97)?'d1:'d0;

assign v_sync = (cnt_v >= 'd3)?'d1:'d0;

endmodule

仿真模塊:

module top_tb;

// Inputs

reg clk;

// Outputs

wire [7:0] doutb;

wire de_o;

wire v_sync;

wire h_sync;

// Instantiate the Unit Under Test (UUT)

top uut (

.clk(clk),

.doutb(doutb),

.de_o(de_o),

.v_sync(v_sync),

.h_sync(h_sync)

);

initial begin

// Initialize Inputs

clk = 0;

// Wait 100 ns for global reset to finish

#100;

// Add stimulus here

end

always #5 clk = !clk;

endmodule

仿真結果如下:該仿真結果處理的是30*30大小圖像縮放成64*64圖像,輸入圖像的每一行數據都是1,2,3···30,仿真結果如下所示:

2594ba44-a667-11ec-952b-dac502259ad0.png

經與matlab運算結果做對比,結果完全一致。 ?

原文標題:FPGA學習-基于FPGA的圖像實時縮放

文章出處:【微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。

審核編輯:彭菁

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1629

    文章

    21729

    瀏覽量

    602993
  • 計算機
    +關注

    關注

    19

    文章

    7488

    瀏覽量

    87849
  • 數字圖像處理

    關注

    7

    文章

    103

    瀏覽量

    18917

原文標題:FPGA學習-基于FPGA的圖像實時縮放

文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    基于FPGA實現的自定義浮點數

    基于FPGA實現各種設計的首要前提是理解并掌握數字的表示方法,計算機中的數字表示方法有兩種:定點數表示法和浮點數表示方法。
    發表于 10-10 10:30 ?1446次閱讀

    FPGA verilog浮點數運算

    求用verilog實現浮點數運算的資料,謝謝
    發表于 12-17 21:15

    點數浮點數的區別是什么

    點數浮點數的區別目的:理解定點數浮點數在傅里葉變換(FFT)的實際應用中的選擇單片機中如果需要進行一定的運算(常見的傅里葉變換)時,需
    發表于 02-21 07:22

    何在GCC中為具有FPU的Cortex M4啟用硬件浮點數學運算呢?

    何在GCC中為具有FPU的Cortex M4啟用硬件浮點數學運算呢?
    發表于 08-26 14:43

    擴充浮點運算集是否需要自己在FPGA板子上設置一個定點數轉為浮點數的部分?

    擴充浮點運算集的時候,是否需要自己在FPGA板子上設置一個定點數轉為浮點數的部分?
    發表于 08-11 09:13

    浮點數運算怎么轉換成整數運算

    浮點數運算怎么轉換成整數運算
    發表于 10-12 06:31

    浮點數的表示方法

    浮點數的表示方法  浮點數,是指小數點在數據中的位置可以左右移動的數據。它通常被表示成:    N = M* RE  這里的M(Mantissa)被稱為浮點數
    發表于 10-13 17:13 ?1.6w次閱讀
    <b class='flag-5'>浮點數</b>的表示方法

    浮點數常用的編碼方法

    浮點數常用的編碼方法  前面已經說到,在計算機內,浮點數被表示為如下格式:    通常情況
    發表于 10-13 17:21 ?4483次閱讀
    <b class='flag-5'>浮點數</b>常用的編碼方法

    單片機浮點數運算的源碼設計

    單片機執行程序的過程,實際上就是執行我們所編制程序的過程。即逐條指令的過程。本文詳細介紹了浮點數在單片機中的表示方式和匯編子程序,浮點數比定點數加減法要困難,但是克服了定點數表示范圍小
    的頭像 發表于 03-07 15:19 ?1w次閱讀
    單片機<b class='flag-5'>浮點數</b><b class='flag-5'>運算</b>的源碼設計

    點數浮點數在STM32單片機中使用傅里葉(FFT)變換的理解

    點數浮點數的區別目的:理解定點數浮點數在傅里葉變換(FFT)的實際應用中的選擇單片機中如果需要進行一定的運算(常見的傅里葉變換)時,需
    發表于 12-24 19:22 ?16次下載
    定<b class='flag-5'>點數</b>和<b class='flag-5'>浮點數</b>在STM32單片機中使用傅里葉(FFT)變換的理解

    談一談浮點數的精度問題

    還是要從浮點數的存儲和標識出發來處理該問題,既然浮點數天然就存在一定的誤差,而有時候計算又無法獲得唯一的數值,如下圖所示,浮點數計算出來的實軸上的值都會因為
    的頭像 發表于 08-11 14:28 ?4585次閱讀
    談一談<b class='flag-5'>浮點數</b>的精度問題

    什么是浮點數浮點數在內存中的存儲

    浮點型簡單講就是實數的意思。浮點數在計算機中用以近似表示任意某個實數。
    的頭像 發表于 11-09 11:07 ?5340次閱讀
    什么是<b class='flag-5'>浮點數</b>?<b class='flag-5'>浮點數</b>在內存中的存儲

    什么是浮點數

    Python數據類型第一種:字符串(str)。 Python數據類型第二種:整數(int)。 Python數據類型第三種:浮點數浮點數的英文名是float,浮點數沒有簡寫。
    的頭像 發表于 02-23 14:58 ?4602次閱讀

    FPGA浮點數表示及計算機數值表示規則

    點數硬件實現簡單,但表示的范圍有限,且部分的小數運算IP核只支持浮點數運算,因此這里還需要提到浮點數的相關內容。
    發表于 06-16 15:41 ?1411次閱讀
    <b class='flag-5'>FPGA</b><b class='flag-5'>浮點數</b>表示及計算機數值表示規則

    modbus浮點數怎么讀取

    Modbus是一種通信協議,常用于工業自動化系統中的設備之間的通信。它支持多種數據類型,包括整數、浮點數、字符串等。浮點數在工業領域中廣泛應用,因此了解如何讀取和處理Modbus浮點數
    的頭像 發表于 12-28 14:38 ?6201次閱讀
    主站蜘蛛池模板: 国产三级在线观看免费| 亞洲人妻AV無碼在線視頻| 男人插曲女人身体视频| 久久精品熟女亚洲AV国产| 日韩AV成人无码久久精品老人| 伦理片qvod| 老色哥网站| 久久亚洲精选| 快播苍井空| 美女脱光app| 内射后入在线观看一区| 免费看黄的片多多APP下载| 美女pk精子2小游戏| 伦理片免费秋霞e| 麻豆乱码一卡二卡三卡视频| 榴莲推广APP网站入口官网| 快插我我好湿啊公交车上做| 恋老视频 国产国佬| 美女18黄| 亲女乱h文小兰第一次| 日本高清色片| 色琪琪无码成人AV视频| 爽死你个放荡粗暴小淫货漫画| 熟女人妻水多爽中文字幕| 午夜福利电影| 亚洲精品高清AV在线播放| 亚洲中文字幕无码一去台湾| 优优色影院| 91福利潘春春在线观看| RUNAWAY韩国动漫免费官网版| TUBE8最新日本护士| 国产 日韩 欧美 高清 亚洲| 国产二区自拍| 极品少妇高潮XXXXX| 麻豆精品传媒卡一卡二传媒短视频| 美女洗澡脱得一二干净| 青草精品国产福利在线视频| 玩两个少妇女邻居| 野草视频在线观看| AV无码九九久久| 国产成人一区二区三区在线观看|