为了实现硬件加速而把C code转化为Verilog。
参考的是: http://beiciliang.weebly.com/uploads/2/4/3/1/24316476/verilog.pdf
因为FPGA上的VGA或者ARM-M3上的摄像头模块都需要一些设置和添加模块(frame buffer,等)。所以为了pre-simulation,将图像作为txt 文件读入verilog里面。
1. 所以第一步是MATLAB code: 把图像转化为binary txt 文件。
注意:不通的图像文件的格式不同:如BMP是有(row X col X 3)而PGM则只有1层。因为SIFT里面是用的PGM,所以这个例子里面我就用PGM格式的。
%% transform image into text file
%% read the image in pgm format
tu = imread('file2.pgm');
%% get the size parameter to set in Verilog file
[row, col] = size(tu);
%% transform into 8bit binary number
tutu = dec2bin(tu);
%% get the string length of binary data
len = size(tutu);
%% then simply open tutu and CtrlC+CtrlV to 'img.txt'
2. 当第一步完成后得到binary文档后,就可以在Verilog里面用$readmemh或者$readmemb。 eg:$readmemh("mem3.txt",mem4); 读入。
`timescale 1ns / 1ps
module rotate;
parameter row = 115,
col = 153,
len = row*col;// = 17595;
reg clk;
reg[0:7] mem1[0:len-1];
reg[0:7] mem3[0:len-1];
reg[0:7] mem4[0:len-1];
integer r,c,p,newp,n,x,i,file1,file2;
initial clk=0;
always #5 clk=~clk;
initial
$readmemb("img.txt",mem1); //读入 img.txt 中的数据寄存在 mem1 中
initial
for(c=0;c<col;c=c+1)
begin
for(r=0;r<row;r=r+1)
begin
p=c*row + r; //c*col+r;
newp=col*(row-1-r)+c; //将 153*115 的数据转置并上下颠倒,实现图像翻转
@(posedge clk)
mem3[newp]=mem1[p]; //每周期将 mem2 中的数据寄存 mem3 的新位置中
end
end
initial begin
file1=$fopen("mem3.txt"); //新建 mem3.txt
wait (c==col)
for(x=0;x<len;x=x+1)
$fwrite(file1,"%h ",mem3[x]); //当所有数据寄存在 mem3 中后,写入 mem3.txt(16 进制)
$fclose(file1);
$readmemh("mem3.txt",mem4); //读入 mem3.txt 的数据寄存在 mem4 中
file2=$fopen("result.txt"); //新建 result.txt
for(i=0;i<len;i=i+1)
begin @(posedge clk)
$fwrite(file2,"%d ",mem4[i]); //每周期将寄存在 mem4 中的数据写入 result.txt(十进制)
end
$fclose(file2);
end
endmodule
当Verilog用Iverilog编译之后就可以并用VVP执行后就可以得到输出。注意:Verilog只可以处理2维数组。
3. 现在就可以将结果用MATLAB转换成图像文件来验证了:
%% load dec output from Verilog
qq = load('lena2.txt');
%% transform into binary
qqq = uint8(qq);
%% reshape to size of 'img.pgm'
Q = reshape(qqq, 153, 115);
%% plot
imshow(Q);
这里分别是输入:
和输出图像: