接下來,就要準(zhǔn)備仿真用數(shù)據(jù)了,我這里用matlab將一副圖片的圖像數(shù)據(jù)取出來,寫成rgb文件,當(dāng)做視頻數(shù)據(jù)源
image=imread('test.bmp');
image=imresize(image,[480,640]);
imshow(image);
w=640;
h=480;
fd=fopen('input.rgb','wb');
for i=1:h
for j=1:w
pix=[0,image(i,j,1),image(i,j,2),image(i,j,3)];
fwrite(fd,pix','uint8');
end
end
fclose(fd);
接下來在sensor模塊里面讀出這個圖像數(shù)據(jù),然后根據(jù)視頻時序發(fā)出
sensor.v代碼
`timescale 1ns / 1ps
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//
// Engineer: EEPROM
//
//////////////////////////////////////////////////////////////////////////////////
module sensor
(
input rst,
input clk,
output reg vsync,
output reg hsync,
output reg de,
output reg vblank,
output reg[31:0]pix_out
);
parameter SENSOR_ACT_W = 640;
parameter SENSOR_ACT_H = 480;
parameter SENSOR_WIDTH = 800;
parameter SENSOR_HEIGHT = 600;
parameter H_START = 80;
parameter V_START = 60;
parameter DATA_SIZE = SENSOR_WIDTH*SENSOR_HEIGHT;
reg [12:0] hcnt;
reg [12:0] vcnt;
reg [31:0] raw_array [DATA_SIZE-1:0];
integer i;
integer file_hdl;
initial
begin
file_hdl = $fopen("input.rgb", "rb");
for ( i=0; i= H_START && hcnt < H_START+SENSOR_ACT_W && vcnt >= V_START && vcnt < V_START+SENSOR_ACT_H )
de <= 1'b1;
else
de <= 1'b0;
end
always @(posedge clk)
begin
if(rst)
begin
vblank <= 1'b1;
end
else if(vcnt >= V_START-1 && vcnt <= V_START+SENSOR_ACT_H )
vblank <= 1'b0;
else
vblank <= 1'b1;
end
always @(posedge clk)
begin
if(rst)
begin
vsync <= 1'b0;
end
else if(vcnt <= 4)
vsync <= 1'b1;
else
vsync <= 1'b0;
end
always @(posedge clk)
pix_out <= (hcnt >= H_START &&hcnt < H_START+SENSOR_ACT_W && vcnt >= V_START && vcnt < V_START+SENSOR_ACT_H) ? raw_array[(vcnt-V_START)*SENSOR_ACT_W+hcnt-H_START]:0;
endmodule
視頻數(shù)據(jù)源有了,那么為了驗證vdma工作正常,即視頻數(shù)據(jù)讀寫ddr正常,就需要把讀回來的數(shù)據(jù)也存儲一下,代碼在tb_top最后有寫,至于為什么要等fram_cnt為1的時候開始寫,那是因為我做的是一個乒乓buffer,vdma讀出來的第一幀數(shù)據(jù)是無效數(shù)據(jù),第二幀開始才是有效數(shù)據(jù)。
代碼都準(zhǔn)備完畢,開始仿真,我這里調(diào)用的modelsim,vivado如果使用modelsim仿真,這里不做介紹,網(wǎng)上搜一下資料還是比較多的
仿真關(guān)鍵信號時序:
這里面是做兩幀的仿真,牢騷一句,仿真真的太慢了
仿真結(jié)束以后,會把從DDR讀回來的視頻數(shù)據(jù)存儲到output.rbg文件里面,還是用matlab對這個數(shù)據(jù)做處理:
w=640;
h=480;
dst = zeros(h,w);
fd=fopen('output.rgb','r');
for i=1:h
for j=1:w
%pix=[0,image(i,j,1),image(i,j,2),image(i,j,3)];
pix=fread(fd,[1,4],'uint8');
dst(i,j)=pix(3);
dst(i,j,2)=pix(2);
dst(i,j,3)=pix(1);
end
end
fclose(fd);
figure
imshow(uint8(dst));
下面是輸入圖片和輸出圖片對比:
可見vdma工作正常
四:總結(jié)
通過對vdma的仿真,可以更深入的了解vdma的工作原理,工作流程,給實際應(yīng)用做好準(zhǔn)備工作。同時,這么做也有更多的意義,對于一些需要DDR緩存才能完成的圖像算法,比如視頻3D降噪,運(yùn)動物體檢測幀差法,HDR圖像合成等等,完全可以在此基礎(chǔ)上進(jìn)行仿真,能更大程度的模擬FPGA實際工作狀況,提高算法移植效率。
評論