色度空间转换CSC(RGB转换YCBCR)的可综合verilog代码编写

原创 2012年03月26日 21:22:32

转载请注明来源。

色度空间转换RGB空间到YCrCb,按以下公式实现转换:

Y  = (0.299R + 0.587G + 0.114B);

Cr = (0.511R - 0.428G - 0.083B) + 128;

Cb = (-0.172R - 0.339G + 0.511B) + 128;

1、定义10组RGB值作为测试向量(文件名:rgb_in.file),编写matlab程序按以上公式转换为YCrCb值。

2、编写可综合的Verilog代码程序(文件名:rgb_to_ycrcb.v)实现以上公式(需有时钟节拍,而非纯组合逻辑),要求添加File Header及Comment信息。

3、编写Testbench(文件名:tb_rgb_to_ycrcb.v),从测试向量文件(文件名:rgb_in.file)读取RGB测试向量值,生成的YCrCb值存入结果文件(文件名:ycrcb_out.file),同时生成波形文件tb_rgb_to_ycrcb.vcd。

4、Verilog仿真后生成的YCrCb值同matlab程序生成的YCrCb值进行比较,看是否一致,如不一致,请分析原因。

5、要求分别采用ModelSim和NCVerilog工具进行仿真,打印提交源代码及波形图,波形图中生成YCrCb值应对齐(即对应同一组RGB值转换而来,应在同一时钟Clock生成;如未对齐,则采用数据延迟。 

程序代码

1.     rgb_in.txt
101011011000110101010011

010110110110101111011010

011011011110111000011011

010101011101001000111101

010100010110101101010100

010101000110011010101010

010111011101110001101010

010110101101010101010101

101001000011101010010101

010110101000100110001110

100010001110101010101011

101011100101000111101101

110101011011011100011001

101011100101011000101010

101010111011100001010101

110111010111101110000010


2.       rgb_to_ycbcr.v

//************************************************************************//

//              Y  = (0.299R + 0.587G + 0.114B);                     //

//              Cr = (0.511R - 0.428G - 0.083B) + 128;             //

//               Cb = (-0.172R - 0.339G + 0.511B) + 128;          //

//*************************************************************************//                                                           

 



`timescale 1ns/10ps

 

module          rgb_to_ycbcr(clk,ngreset,R,G,B,Y,Cb,Cr);

input           clk,ngreset;

input [7:0]     R,G,B;

output[7:0]     Y,Cb,Cr;

wire  [7:0]     Y,Cb,Cr;

/************Y =(1_0011_0010R + 10_0101_1001G + 111_0101B)/1024*************/

reg   [16:0]    r_256_32;

reg   [12:0]    r_16_2;

reg   [17:0]    g_512_64;

reg   [12:0]    g_16_8;

reg   [7:0]     g_1;

reg   [14:0]    b_64_32;

reg   [12:0]    b_16_4;

reg   [7:0]     b_1;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        r_256_32<=17'h1ffff;

        r_16_2  <=13'h1fff; 

        g_512_64<=18'h3ffff;

        g_16_8  <=13'h1fff;

        g_1      <=8'hff;  

        b_64_32 <=15'h7fff;

        b_16_4  <=13'h1fff;

        b_1     <=8'hff;

    end

else

    begin

        r_256_32<={R,8'd0}+{R,5'd0} ;

        r_16_2  <={R,4'd0}+{R,1'd0} ; 

        g_512_64<={G,9'd0}+{G,6'd0} ;

        g_16_8  <={G,4'd0}+{G,3'd0} ;

        g_1     <=G; 

        b_64_32 <={B,6'd0}+{B,5'd0} ;

        b_16_4  <={B,4'd0}+{B,2'd0} ;

        b_1     <=B;

    end

 

reg[17:0]       r_256_32_16_2; 

reg[17:0]       g_512_64_16_8;       

reg[7:0]        g_1_d1;

reg[17:0]       b_64_32_16_4;

reg[7:0]        b_1_d1;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        r_256_32_16_2<=18'h3ffff;

        g_512_64_16_8<=18'h3ffff;

        g_1_d1       <=8'hff;     

        b_64_32_16_4 <=18'h3ffff;

        b_1_d1       <=8'hff;

    end

else

    begin

       r_256_32_16_2<=r_256_32+r_16_2;

       g_512_64_16_8<=g_512_64+g_16_8;

        g_1_d1      <=g_1;               

        b_64_32_16_4 <=b_64_32+b_16_4;

        b_1_d1       <=b_1;

    end

 

reg[17:0]       y_r;

reg[17:0]       y_g;

reg[17:0]       y_b;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

             y_r <=18'h3ffff;

             y_g <=18'h3ffff;

             y_b <=18'h3ffff;

    end 

else

    begin

             y_r <=r_256_32_16_2;

             y_g <=g_512_64_16_8+g_1_d1;

             y_b <=b_64_32_16_4+b_1_d1;

    end 

 

reg[17:0]       y_rg;

reg[17:0]       y_b_d1;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        y_rg   <=18'h0;

        y_b    <=18'h0;

    end

else

    begin

               y_rg   <=y_r+y_g;

        y_b_d1   <=y_b;

    end

 

reg[17:0]       y_rgb;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    y_rgb<=18'h0;

else

    y_rgb<=y_rg+y_b_d1;

 

wire[7:0]       y_tmp;

assign          y_tmp=y_rgb[17:10];

/***************Cr = (10_0000_1011R - 1_1011_0110G - 101_0101B)/1024 + 128**************/

reg[17:0]       r_512_8;

reg[9:0]        r_2_1;      

reg[16:0]       g_256_128;      

reg[13:0]       g_32_16;      

reg[10:0]        g_4_2;      

reg[14:0]       b_64_16;      

reg[10:0]        b_4_1;         

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        r_512_8  <= 18'h1ffff;

        r_2_1    <= 10'h3ff;

        g_256_128<= 17'h1ffff;

        g_32_16  <= 14'h3fff;

        g_4_2    <= 11'h7ff;

        b_64_16  <= 15'h7fff;

        b_4_1    <= 11'h7ff;

    end

else

    begin

        r_512_8  <={R,9'd0}+{R,3'd0} ;

        r_2_1    <={R,1'd0}+R; 

        g_256_128<={G,8'd0}+{G,7'd0} ;

        g_32_16  <={G,5'd0}+{G,4'd0} ;

        g_4_2    <={G,2'd0}+{G,1'd0} ; 

        b_64_16  <={B,6'd0}+{B,4'd0} ;

        b_4_1    <={B,2'd0}+B;

    end

 

reg[17:0]       r_512_8_2_1; 

reg[17:0]       g_256_128_32_16;       

reg[10:0]        g_4_2_d1;

reg[17:0]       b_64_16_4_1;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        r_512_8_2_1     <=18'h3ffff;

        g_256_128_32_16 <=18'h3ffff;

        g_4_2_d1        <=11'hff;     

        b_64_16_4_1     <=18'h3ffff;

    end

else

    begin

        r_512_8_2_1     <= r_512_8+r_2_1;

        g_256_128_32_16 <= g_256_128+g_32_16;

        g_4_2_d1        <= g_4_2;

        b_64_16_4_1     <= b_64_16+b_4_1;

    end

 

reg[17:0]       r_512_8_2_1_d1;   

reg[17:0]       g_256_128_32_16_4_2;

reg[17:0]       b_64_16_4_1_d1;     

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        r_512_8_2_1_d1     <=18'h3ffff;     

        g_256_128_32_16_4_2<=18'h3ffff;

        b_64_16_4_1_d1     <=18'h3ffff;       

    end

else

    begin

        r_512_8_2_1_d1     <=r_512_8_2_1;     

        g_256_128_32_16_4_2<=g_256_128_32_16+g_4_2_d1;

        b_64_16_4_1_d1     <=b_64_16_4_1;

    end       

 

reg[17:0]       cr_r;

reg[17:0]       cr_gb;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

               cr_r <=18'd0;

               cr_gb<=18'd0;

    end 

else

    begin

        cr_r <=r_512_8_2_1_d1;

        cr_gb<=g_256_128_32_16_4_2+b_64_16_4_1_d1;

    end

 

reg[17:0]     cr_rgb;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    cr_rgb<=18'h0;

else if(cr_r>cr_gb)

    cr_rgb<=cr_r-cr_gb;

else

    cr_rgb<=cr_gb-cr_r;

 

wire[7:0]     cr_rgb_d;

assign cr_rgb_d=cr_rgb[17:10];

 

reg[17:0]       cr_r_d1;

reg[17:0]       cr_gb_d1;    

always@(posedge clk or negedge ngreset)

if(!ngreset)

    {cr_r_d1,cr_gb_d1}<=36'h0;

else

    {cr_r_d1,cr_gb_d1}<={cr_r,cr_gb};

 

reg[7:0]        cr_tmp;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    cr_tmp<=8'd0;

else if(cr_r_d1>cr_gb_d1)

    cr_tmp<=8'd128+cr_rgb_d;

else

    cr_tmp<=8'd128-cr_rgb_d;

/***********Cb = (-1011_0000R - 1_0101_1011G + 10_0000_1011B)/1024 + 128********/

reg[15:0]       r_128_32;

reg[12:0]       r_16;

reg[16:0]       g_256_64;

reg[9:0]        g_2_1;

reg[17:0]       b_512_8;

reg[9:0]        b_2_1;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        r_128_32<=16'hffff;

        r_16    <=13'h1fff;   

        g_256_64<=17'h1ffff;

        g_2_1   <=10'h3ff;  

        b_512_8 <=18'h3ffff;

        b_2_1   <=10'h3ff;  

    end

else

    begin

        r_128_32<={R,7'd0}+{R,5'd0} ;

        r_16    <={R,4'd0}; 

        g_256_64<={G,8'd0}+{G,6'd0} ;

        g_2_1   <={G,1'd0}+G ; 

        b_512_8 <={B,9'd0}+{B,3'd0} ;

        b_2_1   <={B,1'd0}+B ;

    end

 

reg[17:0]       r_128_32_16; 

reg[17:0]       g_256_64_16_8;       

reg[9:0]        g_2_1_d1;

reg[17:0]       b_512_8_2_1;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        r_128_32_16  <=18'h3ffff;

        g_256_64_16_8<=18'h3ffff;

        g_2_1_d1     <=10'h3ff;     

        b_512_8_2_1  <=18'h3ffff;

    end

else

    begin

        r_128_32_16   <= r_128_32+r_16;

        g_256_64_16_8 <= g_256_64+g_16_8;

        g_2_1_d1      <= g_2_1;

        b_512_8_2_1   <= b_512_8+b_2_1;

    end

   

 

reg[17:0]  cb_r;

reg[17:0]  cb_g;

reg[17:0]  cb_b;

always@(posedge clk or negedge ngreset)

    if(!ngreset)

    begin

               cb_r<=18'h3ffff;

               cb_g<=18'h3ffff;

               cb_b<=18'h3ffff;

    end

else

    begin

               cb_r<=r_128_32_16;

               cb_g<=g_256_64_16_8+g_2_1_d1;

               cb_b<=b_512_8_2_1;

    end

 

reg[17:0]       cb_rg;

reg[17:0]       cb_b_d1;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    begin

        cb_rg<=18'h3ffff;

        cb_b_d1<=18'h3ffff;

    end

else

    begin

               cb_rg<=cb_r+cb_g;

               cb_b_d1<=cb_b;

    end

 

reg[17:0]       cb_rgb;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    cb_rgb<=18'h3ffff;

else if(cb_rg>cb_b_d1)

    cb_rgb<=cb_rg-cb_b_d1;

else

    cb_rgb<=cb_b_d1-cb_rg;

 

wire[7:0]       cb_rgb_d1;

assign          cb_rgb_d1=cb_rgb[17:10];

reg[7:0]        cb_tmp;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    cb_tmp<=8'h0;

else if(cb_rg>cb_b_d1)

    cb_tmp<=8'd128-cb_rgb_d1;

else

    cb_tmp<=8'd128+cb_rgb_d1;

 

reg[7:0]        y_tmp_d1;

always@(posedge clk or negedge ngreset)

if(!ngreset)

    y_tmp_d1<=8'd0;

else

    y_tmp_d1<=y_tmp;

 

assign          Y=y_tmp_d1;

assign          Cb=cb_tmp;

assign          Cr=cr_tmp;

endmodule

3.       tb_rgb_to_ycbcr.v

`timescale 1ns/1ps

module          tb_rgb_to_ycbcr();

reg             clk,ngreset;

wire [7:0]      R,G,B;

wire [7:0]      Y,Cb,Cr;

initial

    begin

              clk=0;

            ngreset=1;

             #50  ngreset=0;

             #100 ngreset=1;

    end

always       #5 clk=~clk;

 

reg[23:0]       rgb_in[0:15];

initial begin

            $readmemb("rgb_in.txt",rgb_in);

end

integer i;

always@(posedge clk or negedge ngreset)

    if(!ngreset)

       i<=0;

    else if(i==15)

       i<=0;

    else

       i<=i+1;

wire[23:0]      data;

assign          data=rgb_in[i];

assign               R = data[23:16];

assign               G = data[15:8 ];

assign               B = data[7 :0 ]; 

rgb_to_ycbcr  rgb_to_ycbcr_tmpt(.R(R),

                                .G(G),

                                .B(B),

                                .clk(clk),

                                .ngreset(ngreset),

                                .Y(Y),

                                .Cb(Cb),

                                .Cr(Cr));

initial

begin

           $fsdbDumpfile("csc.fsdb");

           $fsdbDumpvars(0,tb_rgb_to_ycbcr);

           #100000  $finish;

end

//initial begin

//      $dumpfile("ycbcr_out.dump");

//      $dumplimit(409600);

//      $dumpvars(0,rgb_to_ycbcr_tmpt);

//      $dumpvars(0,rgb_to_ycbcr_tmpt.Y,rgb_to_ycbcr_tmpt.Cb,rgb_to_ycbcr_tmpt.Cr);

//end

endmodule
仿真波形图

1.  Modelsim仿真波形图

2.  Nc-verilog仿真波形图

总结

1.   由于本代码采用可综合的代码方式编写,因此代码的长度较长,例如加法时候只相加两个数,用移位的方式实现乘法,以后可以采用乘法器加以改进。

2.   本代码完整实现了色度空间转换的任务,并且是可综合的代码,最后输出的YCBCR信号比输入的RGB信号延迟了6个时钟,三个输出信号实现对齐。

3.   通过本代码的编写熟悉了从文件中读取数据和输出数据到文件的过程。

4.  熟悉了通过移位实现乘法的思想,对以后编写代码有启发意义。




Kubernetes 1.2 新功能介绍:Limit Range和Resource Quota

http://www.dockerinfo.net/1123.html 什么是资源的限制范围和使用配额 Docker或者说以Docker发轫的新一代云计算,很大...

RGB与YCbCr颜色空间的转换

YCbCr是YUV经过缩放和偏移的翻版,可以看做YUV的子集。主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视。与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立...

RGB与YCbCr颜色空间的互相转换公式

Y:明亮度(Luminance或Luma),也就是灰阶值。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。 Cb:反映的是RGB输入信号蓝色部分与RGB信号亮度...

RGB与Ycbcr空间的互相转换

一、RGB与Ycbcr转换的公式 1.RGB表示三原色:红绿蓝 Y:表示明亮度,也就是灰阶值。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。 Cb:反映的...

RGB 与 (RGB转 YCbCr再转为 RGB)的图像

RGB 与 (RGB转 YCbCr再转为 RGB)的图像   不可逆,可以从 矩阵的逆运算看出来。 附上 matlab 代码:         clc,clear; Source=imread('1...

色彩空间Lab和RGB互转的Matlab代码

来源:http://www.mathworks.com/matlabcentral/fileexchange/24009-rgb2lab/content/RGB2Lab.m和http://www.ma...

Verilog存储器memory详解

       存储器是一个寄存器数组。存储器使用如下方式说明:     reg [ msb: 1sb] memory1 [ upper1: lower1],     memory2 [upper2: ...

转:RGB与YCbCr颜色空间的转换(高精度测试)

RGB与YCbCr颜色空间的转换     在人脸检测中会用到YCbCr颜色空间,因此就要进行RGB与YCbCr颜色空间的转换,刚开始以为这个很简单,只不是加减乘除的问题,根据公式就可以了,但事实是有...

关于YCbCr与RGB间转换公式推导

  • 2014年06月24日 11:18
  • 216KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:色度空间转换CSC(RGB转换YCBCR)的可综合verilog代码编写
举报原因:
原因补充:

(最多只允许输入30个字)