Verilog笔记——YUV2RGB的模块测试

时间:2022-03-28 08:15:04

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的代码如下:

Verilog笔记——YUV2RGB的模块测试Verilog笔记——YUV2RGB的模块测试
`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);

Verilog笔记——YUV2RGB的模块测试

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