色度空间转换CSC(RGB转换YCBCR)的可综合verilog代码编写
2012-03-26 21:22
761 查看
转载请注明来源。
色度空间转换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
2. rgb_to_ycbcr.v
1. Modelsim仿真波形图
2. Nc-verilog仿真波形图
总结
1. 由于本代码采用可综合的代码方式编写,因此代码的长度较长,例如加法时候只相加两个数,用移位的方式实现乘法,以后可以采用乘法器加以改进。
2. 本代码完整实现了色度空间转换的任务,并且是可综合的代码,最后输出的YCBCR信号比输入的RGB信号延迟了6个时钟,三个输出信号实现对齐。
3. 通过本代码的编写熟悉了从文件中读取数据和输出数据到文件的过程。
4. 熟悉了通过移位实现乘法的思想,对以后编写代码有启发意义。
色度空间转换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; endmodule3. 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. 熟悉了通过移位实现乘法的思想,对以后编写代码有启发意义。
相关文章推荐
- (原创)用verilog实现RGB格式图像到YCbCr或YUV格式的转换及其验证方法 (RGB2YCrCb)(RGB2YUV)
- 用verilog实现RGB名目图像到YCbCr或YUV名目的转换及其验证方法
- 转:RGB与YCbCr颜色空间的转换(高精度测试)
- RGB与YCbCr颜色空间的转换
- RGB ,YUV, YCbCr的定义,YUV 与 RGB相互转换
- RGB与YCbCr颜色空间的转换
- [编写高质量代码:改善java程序的151个建议]建议65 避开基本类型数组转换列表陷阱
- [VHDL+Verilog]良好的代码编写风格(二十五条)
- yuv420和rgb24的转换代码
- Verilog代码编写规范
- cordic算法的总结和verilog代码的编写
- RGB空间与HSL空间转换matlab代码
- js方法实现rgb颜色转换成16进制格式的代码的方法
- 编写安全代码:再论整数类型转换
- C语言编写smtp用户代理之代码综合和管理
- Cocos2d-x创建和转换场景学习笔记 分类: cocos2d代码编写 2015-07-27 17:38 8人阅读 评论(0) 收藏
- 搞摄像头的驱动 YCbCr如何转换为RGB格式
- verilog 编写代码的顺序问题
- 编写安全代码:再论整数类型转换
- RGB与YCbCr颜色空间的转换