• YCbCr2转换成RGB的verilog解析_zt


    http://blog.csdn.net/a14730497/article/details/17887159

    module YCbCr2RGB (
    2   input        iCLK,
    3   input        iRESET,
    4   input        iDVAL,
    5   input  [7:0] iY,
    6   input  [7:0] iCb,
    7   input  [7:0] iCr,
    8   output reg   oDVAL,
    9   output [9:0] Red,
    10   output [9:0] Green,
    11   output [9:0] Blue
    12 );
    13 
    14 // Internal Registers/Wires
    15 reg  [9:0]  oRed,oGreen,oBlue;
    16 reg  [3:0]  oDVAL_d;
    17 reg  [19:0] X_OUT,Y_OUT,Z_OUT;
    18 wire [26:0] X,Y,Z;
    19 
    20 assign Red   = oRed;
    21 assign Green = oGreen;
    22 assign Blue  = oBlue;
    23 
    24 always@(posedge iCLK) begin
    25   if (iRESET) begin
    26     oDVAL   <= 0;
    27     oDVAL_d <= 0;
    28     oRed    <= 0;
    29     oGreen  <= 0;
    30     oBlue   <= 0;
    31   end
    32   else begin
    33     // Red
    34     if (X_OUT[19])
    35       oRed <= 0;
    36     else if (X_OUT[18:0] > 1023)
    37       oRed <= 1023;
    38     else
    39       oRed <= X_OUT[9:0];
    40 
    41     // Green
    42     if (Y_OUT[19])
    43       oGreen<=0;
    44     else if (Y_OUT[18:0] > 1023)
    45       oGreen<=1023;
    46     else
    47       oGreen<=Y_OUT[9:0];
    48       
    49     // Blue
    50     if (Z_OUT[19])
    51       oBlue<=0;
    52     else if (Z_OUT[18:0] > 1023)
    53       oBlue<=1023;
    54     else
    55       oBlue<=Z_OUT[9:0];
    56 
    57     // Control
    58     {oDVAL, oDVAL_d} <= {oDVAL_d, iDVAL};
    59   end
    60 end
    61 
    62 always@(posedge iCLK) begin
    63   if (iRESET) begin
    64     X_OUT <= 0;
    65     Y_OUT <= 0;
    66     Z_OUT <= 0;
    67   end
    68   else begin
    69     X_OUT <= ( X - 114131 ) >>7;
    70     Y_OUT <= ( Y + 69370  ) >>7;
    71     Z_OUT <= ( Z - 141787 ) >>7;
    72   end
    73 end
    74 
    75 // Y 596, 0, 817
    76 MAC_3 u0 (
    77   iY, iCb, iCr,
    78   17'h00254, 17'h00000, 17'h00331,
    79   X, iRESET, iCLK
    80 );
    81   
    82 // Cb 596, -200, -416
    83 MAC_3 u1 (
    84   iY, iCb, iCr,
    85   17'h00254, 17'h3FF38, 17'h3FE60,
    86   Y, iRESET, iCLK
    87 );
    88 
    89 // Cr 596, 1033, 0
    90 MAC_3 u2 (
    91   iY, iCb, iCr,
    92   17'h00254, 17'h00409, 17'h00000,
    93   Z, iRESET, iCLK
    94 );
    95 

    96 endmodule

    //-------------------------------------------------

    转换公式

    R = 1.164Y                + 1.596Cr - 222.912
    G = 1.164Y - 0.391Cb - 0.813Cr + 135.488
    B = 1.164Y + 2.018Cb                - 276.928

    verilog 语法无法处理浮点型数据,将整个算法式先放大处理,然后在缩小。

    现在先将算式左右两边放大512倍,相当于2^9,也就是    << 9,这里也可以*1024  << 10 ,如下:

    R >> 9 = 596Y          + 817Cr - 114131
    G >> 9 = 596Y - 200Cb  - 416Cr + 69370
    B >> 9 = 596Y + 1033Cb         - 141787

    这里调用megafuction 主要是这里有乘法运算,这样方便。直接调用IP核来解决这问题,也可以编写相应的verilog代码,

    只不过消耗很多逻辑单元,并且速度也变慢。

    R >> 9 = 596Y          + 817Cr - 114131     

    MAC_3 u0解决这乘法运算。  

    // Y 596, 0, 817
    MAC_3 u0 (
      iY, iCb, iCr,
      17'h00254, 17'h00000, 17'h00331,
      X, iRESET, iCLK
    );

    //----------------------------------------------------------------------------------------------------------------------------------

    R >> 9 = 596Y + 817Cr - 114131,X已經MAC_3算出來了,所以還要減去114131才行,至于为什么要  >> 7。如下:

    X_OUT <= ( X - 114131 ) >>7;
    Y_OUT <= ( Y + 69370  ) >>7;
    Z_OUT <= ( Z - 141787 ) >>7;

    其实是这样的写法如下:

    X_OUT <= (( X - 114131 ) >> 9) << 2;
    Y_OUT <= (( Y + 69370  ) >> 9) << 2;
    Z_OUT <= (( Z - 141787 ) >> 9) << 2;

    原本算式經過 <<9 放大,最後要用 >>9 還原,這很合理,但別忘了output [9:0] Red是10 bit,而input  [7:0] iY是8 bit,所以最後還得放大 <<2 才行,一來一往就變成 >> 7了。如下:

    X_OUT <= ( X - 114131 ) >>7;
    Y_OUT <= ( Y + 69370  ) >>7;
    Z_OUT <= ( Z - 141787 ) >>7;

    //--------------------------------------------------

    由於做了放大再縮小的運算,難免會造成overflow的狀況,所以最後多加了判斷,若大於1023,就當1023記,若小於0,就當成0,這樣結果才合理。

    // Red
    if (X_OUT[19])
      oRed <= 0;
    else if (X_OUT[18:0] > 1023)
      oRed <= 1023;
    else
      oRed <= X_OUT[9:0];

    // Green
    if (Y_OUT[19])
      oGreen<=0;
    else if (Y_OUT[18:0] > 1023)
      oGreen<=1023;
    else
      oGreen<=Y_OUT[9:0];
          
    // Blue
    if (Z_OUT[19])
      oBlue<=0;
    else if (Z_OUT[18:0] > 1023)
      oBlue<=1023;
    else
      oBlue<=Z_OUT[9:0];

    原文地址:http://www.cnblogs.com/oomusou/archive/2008/12/09/verilog_ycrcb2rgb.html#commentform

  • 相关阅读:
    WCF系列教程之WCF服务配置工具
    WCF系列教程之WCF服务配置
    C# 多线程系列之异步回调(委托)
    WCF系列教程之消息交换模式之请求与答复模式(Request/Reply)
    C# ref与out关键字解析
    WCF系列教程之WCF消息交换模式之单项模式
    WCF系列教程之初识WCF
    C# 装箱和拆箱
    C# checked和unchecked运算符
    Specified key was too long; max key length is 1000 bytes问题解决
  • 原文地址:https://www.cnblogs.com/agllero/p/4448323.html
Copyright © 2020-2023  润新知