1 |
2 |
davidklun |
/////////////////////////////////////////////////////////////////////
|
2 |
|
|
//// ////
|
3 |
|
|
//// JPEG Encoder Core - Verilog ////
|
4 |
|
|
//// ////
|
5 |
|
|
//// Author: David Lundgren ////
|
6 |
|
|
//// davidklun@gmail.com ////
|
7 |
|
|
//// ////
|
8 |
|
|
/////////////////////////////////////////////////////////////////////
|
9 |
|
|
//// ////
|
10 |
|
|
//// Copyright (C) 2009 David Lundgren ////
|
11 |
|
|
//// davidklun@gmail.com ////
|
12 |
|
|
//// ////
|
13 |
|
|
//// This source file may be used and distributed without ////
|
14 |
|
|
//// restriction provided that this copyright statement is not ////
|
15 |
|
|
//// removed from the file and that any derivative work contains ////
|
16 |
|
|
//// the original copyright notice and the associated disclaimer.////
|
17 |
|
|
//// ////
|
18 |
|
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
19 |
|
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
20 |
|
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
21 |
|
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
22 |
|
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
23 |
|
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
24 |
|
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
25 |
|
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
26 |
|
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
27 |
|
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
28 |
|
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
29 |
|
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
30 |
|
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
31 |
|
|
//// ////
|
32 |
|
|
/////////////////////////////////////////////////////////////////////
|
33 |
|
|
|
34 |
|
|
/* This module converts the incoming Red, Green, and Blue 8-bit pixel data
|
35 |
|
|
into Y, Cb, and Cr 8-bit values. The output values will be unsigned
|
36 |
|
|
in the range of 0 to 255.
|
37 |
|
|
data_in contains the Red pixel value in bits [7:0], Green in bits [15:8],
|
38 |
|
|
and Blue in bits [23:16].
|
39 |
|
|
data_out contains the Y value in bits [7:0], Cb value in bits [15:8],
|
40 |
|
|
and Cr balue in bits [23:16].*/
|
41 |
|
|
|
42 |
|
|
`timescale 1ns / 100ps
|
43 |
|
|
|
44 |
|
|
module RGB2YCBCR(clk, rst, enable, data_in, data_out,
|
45 |
|
|
enable_out);
|
46 |
|
|
input clk;
|
47 |
|
|
input rst;
|
48 |
|
|
input enable;
|
49 |
|
|
input [23:0] data_in;
|
50 |
|
|
output [23:0] data_out;
|
51 |
|
|
output enable_out;
|
52 |
|
|
|
53 |
|
|
|
54 |
|
|
wire [13:0] Y1 = 14'd4899;
|
55 |
|
|
wire [13:0] Y2 = 14'd9617;
|
56 |
|
|
wire [13:0] Y3 = 14'd1868;
|
57 |
|
|
wire [13:0] CB1 = 14'd2764;
|
58 |
|
|
wire [13:0] CB2 = 14'd5428;
|
59 |
|
|
wire [13:0] CB3 = 14'd8192;
|
60 |
|
|
wire [13:0] CR1 = 14'd8192;
|
61 |
|
|
wire [13:0] CR2 = 14'd6860;
|
62 |
|
|
wire [13:0] CR3 = 14'd1332;
|
63 |
|
|
reg [21:0] Y_temp, CB_temp, CR_temp;
|
64 |
|
|
reg [21:0] Y1_product, Y2_product, Y3_product;
|
65 |
|
|
reg [21:0] CB1_product, CB2_product, CB3_product;
|
66 |
|
|
reg [21:0] CR1_product, CR2_product, CR3_product;
|
67 |
|
|
reg [7:0] Y, CB, CR;
|
68 |
|
|
reg enable_1, enable_2, enable_out;
|
69 |
|
|
wire [23:0] data_out = {CR, CB, Y};
|
70 |
|
|
|
71 |
|
|
always @(posedge clk)
|
72 |
|
|
begin
|
73 |
|
|
if (rst) begin
|
74 |
|
|
Y1_product <= 0;
|
75 |
|
|
Y2_product <= 0;
|
76 |
|
|
Y3_product <= 0;
|
77 |
|
|
CB1_product <= 0;
|
78 |
|
|
CB2_product <= 0;
|
79 |
|
|
CB3_product <= 0;
|
80 |
|
|
CR1_product <= 0;
|
81 |
|
|
CR2_product <= 0;
|
82 |
|
|
CR3_product <= 0;
|
83 |
|
|
Y_temp <= 0;
|
84 |
|
|
CB_temp <= 0;
|
85 |
|
|
CR_temp <= 0;
|
86 |
|
|
end
|
87 |
|
|
else if (enable) begin
|
88 |
|
|
Y1_product <= Y1 * data_in[7:0];
|
89 |
|
|
Y2_product <= Y2 * data_in[15:8];
|
90 |
|
|
Y3_product <= Y3 * data_in[23:16];
|
91 |
|
|
CB1_product <= CB1 * data_in[7:0];
|
92 |
|
|
CB2_product <= CB2 * data_in[15:8];
|
93 |
|
|
CB3_product <= CB3 * data_in[23:16];
|
94 |
|
|
CR1_product <= CR1 * data_in[7:0];
|
95 |
|
|
CR2_product <= CR2 * data_in[15:8];
|
96 |
|
|
CR3_product <= CR3 * data_in[23:16];
|
97 |
|
|
Y_temp <= Y1_product + Y2_product + Y3_product;
|
98 |
|
|
CB_temp <= 22'd2097152 - CB1_product - CB2_product + CB3_product;
|
99 |
|
|
CR_temp <= 22'd2097152 + CR1_product - CR2_product - CR3_product;
|
100 |
|
|
end
|
101 |
|
|
end
|
102 |
|
|
|
103 |
|
|
/* Rounding of Y, CB, CR requires looking at bit 13. If there is a '1' in bit 13,
|
104 |
|
|
then the value in bits [21:14] needs to be rounded up by adding 1 to the value
|
105 |
|
|
in those bits */
|
106 |
|
|
|
107 |
|
|
always @(posedge clk)
|
108 |
|
|
begin
|
109 |
|
|
if (rst) begin
|
110 |
|
|
Y <= 0;
|
111 |
|
|
CB <= 0;
|
112 |
|
|
CR <= 0;
|
113 |
|
|
end
|
114 |
|
|
else if (enable) begin
|
115 |
|
|
Y <= Y_temp[13] ? Y_temp[21:14] + 1: Y_temp[21:14];
|
116 |
|
|
CB <= CB_temp[13] & (CB_temp[21:14] != 8'd255) ? CB_temp[21:14] + 1: CB_temp[21:14];
|
117 |
|
|
CR <= CR_temp[13] & (CR_temp[21:14] != 8'd255) ? CR_temp[21:14] + 1: CR_temp[21:14];
|
118 |
|
|
// Need to avoid rounding if the value in the top 8 bits is 255, otherwise
|
119 |
|
|
// the value would rollover from 255 to 0
|
120 |
|
|
end
|
121 |
|
|
end
|
122 |
|
|
|
123 |
|
|
|
124 |
|
|
always @(posedge clk)
|
125 |
|
|
begin
|
126 |
|
|
if (rst) begin
|
127 |
|
|
enable_1 <= 0;
|
128 |
|
|
enable_2 <= 0;
|
129 |
|
|
enable_out <= 0;
|
130 |
|
|
end
|
131 |
|
|
else begin
|
132 |
|
|
enable_1 <= enable;
|
133 |
|
|
enable_2 <= enable_1;
|
134 |
|
|
enable_out <= enable_2;
|
135 |
|
|
end
|
136 |
|
|
end
|
137 |
|
|
endmodule
|