zoukankan      html  css  js  c++  java
  • Verilog笔记——YUV2RGB的模块测试

    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数据正确时显示的图片

  • 相关阅读:
    C#方法笔记二:四种类型的参数
    C#+AE 判断点是否在面内的方法
    C#:ref和out的联系及区别。
    C#+AE 调整TOCControl控件中图层的显示顺序
    C# 笔记2:面向对象
    AE10.0 Runtime绑定,如何实现
    C#+AE 用MapControl加载栅格格式文件
    Oracle 10g安装之后解锁Scott的方法
    (转载一篇)Windows7与ArcGIS Desktop9.3冲突问题解决(由QQ安装问题引出)(经本人验证已解决)
    C#方法笔记一:C#4.0新特性:命名参数和可选参数
  • 原文地址:https://www.cnblogs.com/hythink/p/5224569.html
Copyright © 2011-2022 走看看