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

posted @ 2015-04-22 18:43  agllero  阅读(395)  评论(0编辑  收藏  举报