标签:
http://blog.csdn.net/a14730497/article/details/17887159
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
标签:
原文地址:http://www.cnblogs.com/agllero/p/4448323.html