Verilog笔记——YUV2RGB的模块测试

来源:互联网 时间:2016-02-28

1 YUV2RGB的模块如下:

 1 module yuv2rgb(

2 clk, //时钟输入

3 rstn, //复位输入,低电平复位

4

5 y_in, //变换前Y分量输出

6 cb_in, //变换前Cb分量输出

7 cr_in, //变换前Cr分量输出

8 ena_in, //待变换数据使能,当它为高时,输入数据有效

9

10 R_out, //变换后R分量输出

11 G_out, //变换后G分量输出

12 B_out, //变换后B分量输出

13 ena_out //变换后数据使能输出

14 );

    测试模块功能的方法:

         step1 用MATLAB读入一张RGB图片,将RGB转成YUV数据保存在txt文件中;

         step2 用该模块把YUV数据转换成RGB数据并保存;

         step3 用MATLAB读取模块转换的RGB数据做显示。

    接下来详细说明step1~3的实现过程。

2 step1 用MATLAB读入一张RGB图片,将RGB转成YUV数据保存在txt文件中;

clc;close all;clear

RGBimg =imread('Penguins_720p.jpg'); %%用画图软件重新调整像素大小得到的720p图片

figure;imshow(RGBimg);

YUVimg = rgb2ycbcr(RGBimg); %%matlab中的转换函数

figure;imshow(YUVimg);

[Hs Vs Dim] = size(YUVimg);

yuvimout = zeros(1,Hs*Vs*Dim);

yuvimout(1:3:Hs*Vs*Dim) = reshape(YUVimg(:,:,1)',1,Hs*Vs); %%Y

yuvimout(2:3:Hs*Vs*Dim) = reshape(YUVimg(:,:,2)',1,Hs*Vs); %%U

yuvimout(3:3:Hs*Vs*Dim) = reshape(YUVimg(:,:,3)',1,Hs*Vs); %%V

fid= fopen('Penguins_720p.txt','w'); %%YUV数据写入到txt

fprintf(fid,'%02x\n',yuvimout); %%2位十六进制格式

fclose(fid);

fid= fopen('Penguins_720p.yuv','rb'); %%用“7yuv”专业软件转换得到的yuv数据

yuvdat = fread(fid,'uint8');

yuvdat = yuvdat';

fclose(fid);

subAB = yuvdat-yuvimout; %%比较下matlab转换的yuv数据

figure;stem(find(subAB~=0));

3 step2 用该模块把YUV数据转换成RGB数据并保存;

testbench的代码如下:

`timescale 1ns / 1ps

module tb_yuv2rgb;

// Inputs

reg clk;

reg rstn; //复位输入,低电平复位

reg [7:0] y_in;

reg [7:0] cb_in;

reg [7:0] cr_in;

reg ena_in;

// Outputs

wire [7:0] R_out;

wire [7:0] G_out;

wire [7:0] B_out;

wire ena_out;

// Instantiate the Unit Under Test (UUT)

yuv2rgb uut (

.clk(clk),

.rstn(rstn),

.y_in(y_in),

.cb_in(cb_in),

.cr_in(cr_in),

.ena_in(ena_in),

.R_out(R_out),

.G_out(G_out),

.B_out(B_out),

.ena_out(ena_out)

);

localparam PIXNUM_1080P =(1920*1080*3);

localparam PIXNUM_720P =(1280*720*3);

//read pixel from .txt file

reg[7:0] mem_imgpixel[0:2**24];

reg [31:0] pixaddr;

integer fid,i;

initial begin //读取图片的YUV数据

$readmemh("Penguins_720p.txt",mem_imgpixel);

pixaddr = 0;

#PIXNUM_1080P begin //等待图片的数据转换完成

fid = $fopen("Penguins_720pRGBout.txt","w");

for(i=0; i<PIXNUM_720P; i=i+1)

$fdisplay(fid,"%2x",mem_rgbout[i]);//输出转换的RGB数据

$fclose(fid);

$stop;

end

end

//clk的上升沿给输入的yuv数据

always @(posedge clk or negedge rstn) begin

if(!rstn) begin

y_in <= 8'b0;

cb_in <= 8'b0;

cr_in <= 8'b0;

ena_in <= 1'b0;

pixaddr<= 0;

end

else begin

y_in <= mem_imgpixel[pixaddr];

cb_in <= mem_imgpixel[pixaddr+1];

cr_in <= mem_imgpixel[pixaddr+2];

ena_in <= 1'b1;

pixaddr<= pixaddr + 3;

end

end

reg[31:0] outaddr;

reg[7:0] mem_rgbout[0:2**24];//clk的下降沿读取转换的rgb数据

always @(negedge clk or negedge rstn) begin

if(!rstn) begin

outaddr <= 0;

end

else begin //存入对应下标

mem_rgbout[outaddr] <= R_out;

mem_rgbout[outaddr+1] <= G_out;

mem_rgbout[outaddr+2] <= B_out;

outaddr <= outaddr + 3; //下标增加3

end

end

initial begin

// Initialize Inputs

clk = 0;

rstn = 1;

y_in = 0;

cb_in = 0;

cr_in = 0;

ena_in = 0;

#2;

rstn = 0;

// Wait 100 ns for global reset to finish

#100;

rstn = 1;

// Add stimulus here

end

always #2 clk =~clk;

endmodule

View Code

 

4 step3 用MATLAB读取模块转换的RGB数据做显示。

clc;close all;clear

filename = 'Penguins_720pRGBout.txt';

fid = fopen(filename,'r');

rgbdat = fscanf(fid,'%x');

rgbdat = uint8(rgbdat'); %%转换为uint8

fclose(fid);

imglen = 1280; imgwidth = 720;

len = length(rgbdat);

r = rgbdat(1:3:len);

r = reshape(r,imglen,imgwidth);

r = r';

g = rgbdat(2:3:len);

g = reshape(g,imglen,imgwidth);

g = g';

b = rgbdat(3:3:len);

b = reshape(b,imglen,imgwidth);

b = b';

rgbimg = cat(3,r,g,b);

imshow(rgbimg);

step3中rgb数据正确时显示的图片

 

相关阅读:
Top