FC2カウンター FPGAの部屋 RGB―YCbCr変換の検討2(Verilog HDLで実装)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

RGB―YCbCr変換の検討2(Verilog HDLで実装)

”RGB―YCbCr変換の検討1(変換式)”の続き。

前回は変換式をVerilog HDLで記述できる形に変換した。今回は、実際にVerilog-HDLでRGB-YCbCr変換を記述した。
まず、RGB-YCbCr変換を行うconv_rgb2ycbcr.v を下に示す。
(2012/11/27:conv_rgb2ycbcr.v を修正しました。以下のインプリメントの回路規模とかが違っている場合があります)

// RGB - YCbCr変換
// Y = 0.257R + 0.504G + 0.098B + 16
// Cb = -0.148R - 0.291G + 0.439B + 128
// Cr = 0.439R - 0.368G - 0.071B + 128
// 但し、Yは255以上だったら飽和演算をして255に丸める。Cb, Crは16以下だったら16に、240以上だったら240に飽和演算を行う。
// 切り捨てバージョン

`default_nettype none

module conv_rgb2ycbcr_round_down (
    input    wire    [7:0]    red,
    input    wire    [7:0]    green,
    input    wire    [7:0]    blue,
    output    reg        [7:0]    y,
    output    reg        [7:0]    cb,
    output    reg        [7:0]    cr
);
    
    wire    [18:0]    y_lshift8;
    wire    [18:0]    cb_lshift8;
    wire    [18:0]    cr_lshift8;
    

    assign y_lshift8 = ({5'd0, red, 6'd0} + {10'd0, red, 1'd0}) +  ({4'd0, green, 7'd0} + {11'd0, green}) + ({7'd0, blue, 4'd0} + {8'd0, blue, 3'd0} + {11'd0, blue}) + 19'd4096;
    
    assign cb_lshift8 = 19'd0 - ({6'd0, red, 5'd0} + {9'd0, red, 2'd0} + {10'd0, red, 1'd0}) - ({5'd0, green, 6'd0} + {8'd0, green, 3'd0} + {10'd0, green, 1'd0}) + ({5'd0, blue, 6'd0} + {6'd0, blue, 5'd0} + {7'd0, blue, 4'd0}) + 19'd32768;
    
    assign cr_lshift8 = ({5'd0, red, 6'd0} + {6'd0, red, 5'd0} + {7'd0, red, 4'd0}) - ({5'd0, green, 6'd0} + {7'd0, green, 4'd0} + {8'd0, green, 3'd0} + {9'd0, green, 2'd0} + {10'd0, green, 1'd0}) - ({7'd0, blue, 4'd0} + {10'd0, blue , 1'd0}) + 19'd32768;
    
    always @* begin
        if (y_lshift8[18] == 1'b1 || y_lshift8[17:8]<16) // マイナスまたは16より小さいので16に丸める
            y <= 8'd16;
        else if (y_lshift8[17:8] > 235) // 235より大きければ235に丸める
            y <= 8'd235;
        else
            y <=  y_lshift8[15:8];
    end
    
    always @* begin
        if (cb_lshift8[18] == 1'b1 || cb_lshift8[17:8]<16) // マイナスまたは16より小さいので16に丸める
            cb <= 8'd16;
        else if (cb_lshift8[17:8] > 240) // 240より大きければ240に丸める
            cb <= 8'd240;
        else
            cb <=  cb_lshift8[15:8];
    end
    
    always @* begin
        if (cr_lshift8[18] == 1'b1 || cr_lshift8[17:8]<16) // マイナスまたは16より小さいので16に丸める
            cr <= 8'd16;
        else if (cr_lshift8[17:8] > 240) // 240より大きければ240に丸める
            cr <= 8'd240;
        else
            cr <=  cr_lshift8[15:8];
    end
endmodule

`default_nettype wire


次に、ISEのプロジェクトを作成して、conv_rgb2ycbcr.v をテストするテストベンチファイルconb_rgb2ycbcr.v を作製した。conb_rgb2ycbcr.v を下に示す。

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   04:57:17 11/18/2012
// Design Name:   conv_rgb2ycbcr
// Module Name:   K:/HDL/FndtnISEWork/Zynq-7000/ZedBoard/test/conv_rgb2ycbcr/conv_rgb2ycbcr_tb.v
// Project Name:  conv_rgb2ycbcr
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: conv_rgb2ycbcr
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module conv_rgb2ycbcr_tb;

    // Inputs
    reg [7:0] red;
    reg [7:0] green;
    reg [7:0] blue;

    // Outputs
    wire [7:0] y;
    wire [7:0] cb;
    wire [7:0] cr;
    
    integer i = 0;
    integer j = 0;
    integer k = 0;

    // Instantiate the Unit Under Test (UUT)
    conv_rgb2ycbcr uut (
        .red(red), 
        .green(green), 
        .blue(blue), 
        .y(y), 
        .cb(cb), 
        .cr(cr)
    );

    initial begin
        // Initialize Inputs
        red = 0;
        green = 0;
        blue = 0;

        // Wait 100 ns for global reset to finish
        #100;
        
        // Add stimulus here
        for (i=0; i < 100; i = i + 10) begin
            red = i;
            green = i;
            blue = i;    // 色は白
            #10;
        end
        
        for (i=0; i<256; i=i+1) begin
            for (j=0; j<256; j=j+1) begin
                for (k=0; k<256; k=k+1) begin
                    red = i;
                    green = j;
                    blue = k;
                    #10;
                end
            end
        end
        
        $finish;
    end
      
endmodule


最初は、RGBとも同じ値をシミュレーションしている。つまり白色をシミュレーションしているわけだ。
白色の場合はYの値は変わるが、Cb, Crの値は128で固定されている。なお、RGBがオール0の場合はYは16となる。下に白色の場合のシミュレーション結果を示す。
Conv_RGB2YCbCr_1_121118.png

シミュレーション結果の一部を下に示す。
Conv_RGB2YCbCr_2_121118.png

(追加)試しにインプリメントしてみました。MAPのリポートの一部を下に示します。

Release 14.3 Map P.40xd (nt)
Xilinx Mapping Report File for Design 'conv_rgb2ycbcr'

Design Information
------------------
Command Line   : map -intstyle ise -p xc7z020-clg484-1 -w -logic_opt off -ol
high -t 1 -xt 0 -register_duplication off -r 4 -mt off -ir off -pr off -lc off
-power off -o conv_rgb2ycbcr_map.ncd conv_rgb2ycbcr.ngd conv_rgb2ycbcr.pcf 
Target Device  : xc7z020
Target Package : clg484
Target Speed   : -1
Mapper Version : zynq -- $Revision: 1.55 $
Mapped Date    : SUN 18 NOV 6:1:11 2012

Design Summary
--------------
Number of errors:      0
Number of warnings:   50
Slice Logic Utilization:
  Number of Slice Registers:                    41 out of 106,400    1%
    Number used as Flip Flops:                   0
    Number used as Latches:                      0
    Number used as Latch-thrus:                  0
    Number used as AND/OR logics:               41
  Number of Slice LUTs:                        240 out of  53,200    1%
    Number used as logic:                      238 out of  53,200    1%
      Number using O6 output only:             117
      Number using O5 output only:               8
      Number using O5 and O6:                  113
      Number used as ROM:                        0
    Number used as Memory:                       0 out of  17,400    0%
    Number used exclusively as route-thrus:      2
      Number with same-slice register load:      0
      Number with same-slice carry load:         2
      Number with other load:                    0

Slice Logic Distribution:
  Number of occupied Slices:                    93 out of  13,300    1%
  Number of LUT Flip Flop pairs used:          240
    Number with an unused Flip Flop:           199 out of     240   82%
    Number with an unused LUT:                   0 out of     240    0%
    Number of fully used LUT-FF pairs:          41 out of     240   17%
    Number of slice register sites lost
      to control set restrictions:               0 out of 106,400    0%

  1. 2012年11月18日 05:57 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog.fc2.com/tb.php/2311-f7ba2e42
この記事にトラックバックする(FC2ブログユーザー)