在没有开发板的情况下,要使用Verilog做图像处理,就只能仿真了。
这时需要一个激励,让Verilog读取到图片,这里就提供一个例子去读取bmp图片。
`timescale 1ns / 1ns
module bmp_tb;
integer iBmpFileId,iOutFileId,iIndex=0,iCode;
reg [7:0] rBmpData [0:200000];
reg rClk;
reg [7:0] rData;
integer iBmpWidth,iBmpHight,iDataStartIndex,iBmpSize;
initial begin
iBmpFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\cat.bmp","rb");
iOutFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\output_file.txt","w+");
iCode = $fread(rBmpData,iBmpFileId);
iBmpWidth = {rBmpData[21],rBmpData[20],rBmpData[19],rBmpData[18]};
iBmpHight = {rBmpData[25],rBmpData[24],rBmpData[23],rBmpData[22]};
iDataStartIndex = {rBmpData[13],rBmpData[12],rBmpData[11],rBmpData[10]};
iBmpSize = {rBmpData[5],rBmpData[4],rBmpData[3],rBmpData[2]};
$fclose(iBmpFileId);
$fwrite(iOutFileId,"%p",rBmpData);
$fclose(iOutFileId);
end
initial begin
forever begin
rClk=1;
#10 rClk = 0;
#10;
end // forever
end // initial
always@(posedge rClk) begin
rData<=rBmpData[iIndex];
iIndex<=iIndex+1;
end
endmodule
注意:其中iBmpFileId和iOutFileId的路径,需要根据你的文件路径而修改。
经过仿真,可以看出Verilog可以读取到bmp图片的信息,从而得到图片的宽、高。
若要输出.bmp图片,可以使用以下代码。
`timescale 1ns / 1ns
module bmp_tb;
integer iBmpFileId,iOutFileId,iIndex=0,iCode;
reg [7:0] rBmpData [0:200000];
reg [31:0] rBmpCom;
reg rClk;
reg [7:0] rData;
integer iBmpWidth,iBmpHight,iDataStartIndex,iBmpSize;
initial begin
iBmpFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\cat.bmp","rb");
iOutFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\output_file.bmp","w+");
iCode = $fread(rBmpData,iBmpFileId);
iBmpWidth = {rBmpData[21],rBmpData[20],rBmpData[19],rBmpData[18]};
iBmpHight = {rBmpData[25],rBmpData[24],rBmpData[23],rBmpData[22]};
iDataStartIndex = {rBmpData[13],rBmpData[12],rBmpData[11],rBmpData[10]};
iBmpSize = {rBmpData[5],rBmpData[4],rBmpData[3],rBmpData[2]};
$fclose(iBmpFileId);
for (iIndex = 0; iIndex < iBmpSize; iIndex = iIndex + 4) begin
rBmpCom = {rBmpData[iIndex+3],rBmpData[iIndex+2],rBmpData[iIndex+1],rBmpData[iIndex]};
$fwrite(iOutFileId,"%u",rBmpCom);
end // for
$fclose(iOutFileId);
end
endmodule
使用的图片,如下图所示,请保存为.bmp格式。
其中输出的.bmp图片中,多了一个字节(0A前面多了0D),会显示如下图所示。
解决办法是使用二进制方法打开文件,即wb+,代码如下:
`timescale 1ns / 1ns
module bmp_tb;
integer iBmpFileId,iOutFileId,iIndex=0,iCode;
reg [7:0] rBmpData [0:200000];
reg [31:0] rBmpCom;
reg rClk;
reg [7:0] rData;
integer iBmpWidth,iBmpHight,iDataStartIndex,iBmpSize;
initial begin
iBmpFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\cat.bmp","rb+");
iOutFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\output_file.bmp","wb+");
iCode = $fread(rBmpData,iBmpFileId);
iBmpWidth = {rBmpData[21],rBmpData[20],rBmpData[19],rBmpData[18]};
iBmpHight = {rBmpData[25],rBmpData[24],rBmpData[23],rBmpData[22]};
iDataStartIndex = {rBmpData[13],rBmpData[12],rBmpData[11],rBmpData[10]};
iBmpSize = {rBmpData[5],rBmpData[4],rBmpData[3],rBmpData[2]};
$fclose(iBmpFileId);
for (iIndex = 0; iIndex < iBmpSize; iIndex = iIndex + 4) begin
rBmpCom = {rBmpData[iIndex+3],rBmpData[iIndex+2],rBmpData[iIndex+1],rBmpData[iIndex]};
$fwrite(iOutFileId,"%u",rBmpCom);
end // for
$fclose(iOutFileId);
end
endmodule
利用这一方法,可以输出直方图、时域图、频域图等,如:使用可综合语句完成FFT的功能,再使用tb让其输出频域图。