2013-01-16 82 views
0

我現在正詳細解釋我的問題,因爲我意識到我沒有很好地解釋我的問題。將8位bmp轉換爲半色調bmp

我是Verilog的初學者。要學習這門語言,我正在編寫一些示例應用程序。
目前我正在編寫Verilog代碼,使用Floyd-Steinberg算法將8位BMP圖像轉換爲半色調BMP圖像。 基本上我使用上述算法將8位像素轉換爲1位。

我在書號爲555的書Advanced Digital Design with the Verilog HDL - Michael D. Ciletti中找到了此算法的示例代碼。我已成功模擬了ModelSim中的設計。

問題是給出了一個大小爲6 x 8的圖像的例子,但要學習和實踐,我試圖將此代碼轉換爲不同的格式和大小。作爲第一個目標,我試圖修改這個代碼(我已經很好的理解了)爲1000 x 1000大小的圖像工作。由於該示例僅適用於48像素(6 x 8),因此編寫指令更容易手動模塊內部,如下面給出的代碼所示。但萬一我有1000萬像素(1000 x 1000),我該如何更改代碼。 我不能寫這樣的方程:

PPDU a0(err_1,htpv_1[1],8'b00,8'b00,8'b00,8'b00,pixel_1); 

10,00000手動(請儘快下面給出的代碼)。

我想必須有一些方法來自動執行這項工作。

在C我可以使用循環 autoamting很多事情。但作爲Verilog的新手,我無法繼續。如果有人能指點我一個有用的鏈接,我會真正aprecaite。

// pixel processor datapath unit// 
module PPDU(err_0,htpv,err_1,err_2,err_3,err_4,pv); 
output [7:0]err_0; 
output htpv; 
input [7:0]err_1,err_2,err_3,err_4,pv; 
wire [9:0]cpv,cpv_round,e_av; 
parameter w1=2,w2=8,w3=4,w4=2; 
parameter threshold =128; 
assign e_av=(w1*err_1+w2*err_2+w3*err_3+w4*err_4)>>4; 
assign cpv=pv+e_av; 
assign cpv_round=(cpv<threshold)?0:255; 
assign htpv=(cpv_round==0)?0:1; 
assign err_0=cpv-cpv_round; 
endmodule 

module image_converter (pixel_1,pixel_2,pixel_3,pixel_4,pixel_5,pixel_6,pixel_7,pixel_8,pixel_9, 
    pixel_10,pixel_11,pixel_12,pixel_13,pixel_14,pixel_15,pixel_16,pixel_17, 
    pixel_18,pixel_19,pixel_20,pixel_21,pixel_22,pixel_23,pixel_24,pixel_25, 
    pixel_26,pixel_27,pixel_28,pixel_29,pixel_30,pixel_31,pixel_32,pixel_33, 
    pixel_34,pixel_35,pixel_36,pixel_37,pixel_38,pixel_39,pixel_40,pixel_41, 
    pixel_42,pixel_43,pixel_44,pixel_45,pixel_46,pixel_47,pixel_48,htpv_1, 
     htpv_2,htpv_3,htpv_4,htpv_5,htpv_6 
    ); 
input [7:0]pixel_1,pixel_2,…..,pixel_47,pixel_48; 
output [1:8]htpv_1,htpv_2,htpv_3,htpv_4,htpv_5,htpv_6; 
wire [7:0]err_1,err_2,……., err_47,err_48; 
PPDU a0(err_1,htpv_1[1],8'b00,8'b00,8'b00,8'b00,pixel_1); 
... 
PPDU a7(err_8,htpv_1[8],err_7,8'b00,8'b00,8'b00,pixel_8);      
PPDU b1(err_9,htpv_2[1],8'b00,8'b00,err_1,err_2,pixel_9); 
...  PPDU b8(err_16,htpv_2[8],err_15,err_7,err_8,8'b00,pixel_16); 
PPDU c1(err_17,htpv_3[1],8'b00,8'b00,err_9,err_2,pixel_17); 
…. 
PPDU c8(err_24,htpv_3[8],err_23,err_15,err_16,8'b00,pixel_24); 
PPDU d1(err_25,htpv_4[1],8'b00,8'b00,err_17,err_18,pixel_25); 
…. 
PPDU d8(err_32,htpv_4[8],err_31,err_23,err_24,8'b00,pixel_32); 
PPDU e1(err_33,htpv_5[1],8'b00,8'b00,err_25,err_26,pixel_33); 
…. 
PPDU e8(err_40,htpv_5[8],err_39,err_31,err_32,8'b00,pixel_40); 
PPDU fi(err_41,htpv_6[1],8'b00,8'b00,err_33,err_34,pixel_41); 
…. 
PPDU f8(err_48,htpv_6[8],err_47,err_39,err_40,8'b00,pixel_40); 
end 
endmodule 

回答

0

兩個想法:

  1. 可以使用generate語句作爲一種循環的實例化哪一個是不勝枚舉打出來的模塊。我對這個構造不太熟悉,但也許是谷歌搜索這個關鍵詞會指向正確的方向。

  2. 儘管verilog是一種硬件描述語言,但沒有什麼要求你真正用手寫出文件。你可以隨意使用你喜歡的任何編程語言來生成verilog文件(Perl是我最喜歡的)。如果您必須根據某種算法生成100萬個模塊,那麼您可以編寫一個簡單的腳本來打印100萬行verilog文件。您不必手動編寫它。

0

這聽起來像你正在爲每個像素實例化一個模塊。這一切都很好,但最終會爲1000x1000圖像使用大量硬件,因爲每個模塊都是一堆門和觸發器。這會導致你轉換整個圖像「一次」,這也意味着你必須將整個圖像一次性地轉移到這個硬件上,這是一個非常多的引腳。

你可能想要做什麼或者是:

  • 在存儲器中存儲的圖像,然後寫一個狀態機來讀取內存的相關部分,執行抖動和寫回
  • 通過某種邏輯流式傳輸圖像,該邏輯只保留前面像素的足夠知識來執行抖動。我並不熟悉F-S抖動,但它可能只需要知道正在處理的一行或兩行以上的知識。