(原創) 如何Real Time產生灰階影像? (SOC) (DE2) (TRDB-DC2)
Abstract
灰階影像是很多電腦視覺演算法的基礎,必須會先會產生灰階影像後,才能繼續動其他演算法。
Introduction
使用環境:Quartus II 7.2 SP3 + DE2(Cyclone II EP2C35F627C6) + TRDB-DC2
RGB轉灰階的演算法
在(原創) 如何將CMOS彩色影像轉換成灰階影像? (SOC) (DE2)曾經討論過如何產生灰階影像,當初只是用簡單的(R+G+B) /3來做,雖然看起來有灰階,但實際上有2個問題:
1.(R+G+B) /3並非正統由RGB轉灰階的方式。
2.需動用到除法,對硬體來說,除法器相當耗resource,能不用盡量不用。
至於怎樣才是正統的RGB轉灰階演算法呢?基本上這已經可以發論文討論了,一般來說,較讓大部分人所接受的公式是
這牽涉到浮點運算,不要說硬體難實現,光用C去寫,執行速度也很不理想,所以才會有人乾脆用(R+G+B) /3來做。若要在硬體實現,勢必再做一些簡化。
注意到R、G、B的權重嗎?G的權重幾乎是R的2倍,B的權重的5倍,所以真正決定灰階程度的關鍵在於G,而R、B的影響較不顯著,所以乾脆就用G來代表灰階,這種方式最有利於硬體實現。
硬體的實現
SDRAM是VGA的frame buffer,要real time產生灰階影像,有兩條路可以走:
1.在SDRAM之前
也就是上圖黃色的Pre-processing之處,因為RGB合起來共30 bit,而灰階只有10 bit,這樣可省下1/2的SDRAM空間(為什麼不是2/3?後面會解釋),且省下一半的頻寬。
2.在SDRAM之後
也就是上圖黃色的Main Processing之處,這種方式雖然無法節省SDRAM,但比較好寫,結果一樣是灰階影像。
何種方式較好?要看實際應用而定,本文兩種方式都會討論。
Method 1:
在SDRAM之前
DE2_CCD.v / Verilog
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3
4 Filename : DE2_CCD.v
5 Compiler : Quartus II 7.2 SP3
6 Description : Demo how to use 130m CMOS to make gray before SDRAM on DE2
7 Release : 08/23/2008 1.0
8 */
9
10 module DE2_CCD (
11 //////////////////////// Clock Input ////////////////////////
12 input CLOCK_27, // 27 MHz
13 input CLOCK_50, // 50 MHz
14 input EXT_CLOCK, // External Clock
15 //////////////////////// Push Button ////////////////////////
16 input [3:0] KEY, // Pushbutton[3:0]
17 //////////////////////// DPDT Switch ////////////////////////
18 input [17:0] SW, // Toggle Switch[17:0]
19 //////////////////////// 7-SEG Dispaly ////////////////////////
20 output [6:0] HEX0, // Seven Segment Digit 0
21 output [6:0] HEX1, // Seven Segment Digit 1
22 output [6:0] HEX2, // Seven Segment Digit 2
23 output [6:0] HEX3, // Seven Segment Digit 3
24 output [6:0] HEX4, // Seven Segment Digit 4
25 output [6:0] HEX5, // Seven Segment Digit 5
26 output [6:0] HEX6, // Seven Segment Digit 6
27 output [6:0] HEX7, // Seven Segment Digit 7
28 //////////////////////////// LED ////////////////////////////
29 output [8:0] LEDG, // LED Green[8:0]
30 output [17:0] LEDR, // LED Red[17:0]
31 //////////////////////////// UART ////////////////////////////
32 output UART_TXD, // UART Transmitter
33 input UART_RXD, // UART Receiver
34 //////////////////////////// IRDA ////////////////////////////
35 output IRDA_TXD, // IRDA Transmitter
36 input IRDA_RXD, // IRDA Receiver
37 /////////////////////// SDRAM Interface ////////////////////////
38 inout [15:0] DRAM_DQ, // SDRAM Data bus 16 Bits
39 output [11:0] DRAM_ADDR, // SDRAM Address bus 12 Bits
40 output DRAM_LDQM, // SDRAM Low-byte Data Mask
41 output DRAM_UDQM, // SDRAM High-byte Data Mask
42 output DRAM_WE_N, // SDRAM Write Enable
43 output DRAM_CAS_N, // SDRAM Column Address Strobe
44 output DRAM_RAS_N, // SDRAM Row Address Strobe
45 output DRAM_CS_N, // SDRAM Chip Select
46 output DRAM_BA_0, // SDRAM Bank Address 0
47 output DRAM_BA_1, // SDRAM Bank Address 0
48 output DRAM_CLK, // SDRAM Clock
49 output DRAM_CKE, // SDRAM Clock Enable
50 //////////////////////// Flash Interface ////////////////////////
51 inout [7:0] FL_DQ, // FLASH Data bus 8 Bits
52 output [21:0] FL_ADDR, // FLASH Address bus 22 Bits
53 output FL_WE_N, // FLASH Write Enable
54 output FL_RST_N, // FLASH Reset
55 output FL_OE_N, // FLASH Output Enable
56 output FL_CE_N, // FLASH Chip Enable
57 //////////////////////// SRAM Interface ////////////////////////
58 inout [15:0] SRAM_DQ, // SRAM Data bus 16 Bits
59 output [17:0] SRAM_ADDR, // SRAM Address bus 18 Bits
60 output SRAM_UB_N, // SRAM High-byte Data Mask
61 output SRAM_LB_N, // SRAM Low-byte Data Mask
62 output SRAM_WE_N, // SRAM Write Enable
63 output SRAM_CE_N, // SRAM Chip Enable
64 output SRAM_OE_N, // SRAM Output Enable
65 //////////////////// ISP1362 Interface ////////////////////////
66 inout [15:0] OTG_DATA, // ISP1362 Data bus 16 Bits
67 output [1:0] OTG_ADDR, // ISP1362 Address 2 Bits
68 output OTG_CS_N, // ISP1362 Chip Select
69 output OTG_RD_N, // ISP1362 Write
70 output OTG_WR_N, // ISP1362 Read
71 output OTG_RST_N, // ISP1362 Reset
72 output OTG_FSPEED, // USB Full Speed, 0 = Enable, Z = Disable
73 output OTG_LSPEED, // USB Low Speed, 0 = Enable, Z = Disable
74 input OTG_INT0, // ISP1362 Interrupt 0
75 input OTG_INT1, // ISP1362 Interrupt 1
76 input OTG_DREQ0, // ISP1362 DMA Request 0
77 input OTG_DREQ1, // ISP1362 DMA Request 1
78 output OTG_DACK0_N, // ISP1362 DMA Acknowledge 0
79 output OTG_DACK1_N, // ISP1362 DMA Acknowledge 1
80 //////////////////// LCD Module 16X2 ////////////////////////////
81 inout [7:0] LCD_DATA, // LCD Data bus 8 bits
82 output LCD_ON, // LCD Power ON/OFF
83 output LCD_BLON, // LCD Back Light ON/OFF
84 output LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read
85 output LCD_EN, // LCD Enable
86 output LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data
87 //////////////////// SD Card Interface ////////////////////////
88 inout SD_DAT, // SD Card Data
89 inout SD_DAT3, // SD Card Data 3
90 inout SD_CMD, // SD Card Command Signal
91 output SD_CLK, // SD Card Clock
92 //////////////////////// I2C ////////////////////////////////
93 inout I2C_SDAT, // I2C Data
94 output I2C_SCLK, // I2C Clock
95 //////////////////////// PS2 ////////////////////////////////
96 input PS2_DAT, // PS2 Data
97 input PS2_CLK, // PS2 Clock
98 //////////////////// USB JTAG link ////////////////////////////
99 input TDI, // CPLD -> FPGA (data in)
100 input TCK, // CPLD -> FPGA (clk)
101 input TCS, // CPLD -> FPGA (CS)
102 output TDO, // FPGA -> CPLD (data out)
103 //////////////////////// VGA ////////////////////////////
104 output VGA_CLK, // VGA Clock
105 output VGA_HS, // VGA H_SYNC
106 output VGA_VS, // VGA V_SYNC
107 output VGA_BLANK, // VGA BLANK
108 output VGA_SYNC, // VGA SYNC
109 output [9:0] VGA_R, // VGA Red[9:0]
110 output [9:0] VGA_G, // VGA Green[9:0]
111 output [9:0] VGA_B, // VGA Blue[9:0]
112 //////////////// Ethernet Interface ////////////////////////////
113 inout [15:0] ENET_DATA, // DM9000A DATA bus 16Bits
114 output ENET_CMD, // DM9000A Command/Data Select, 0 = Command, 1 = Data
115 output ENET_CS_N, // DM9000A Chip Select
116 output ENET_WR_N, // DM9000A Write
117 output ENET_RD_N, // DM9000A Read
118 output ENET_RST_N, // DM9000A Reset
119 input ENET_INT, // DM9000A Interrupt
120 output ENET_CLK, // DM9000A Clock 25 MHz
121 //////////////////// Audio CODEC ////////////////////////////
122 inout AUD_ADCLRCK, // Audio CODEC ADC LR Clock
123 input AUD_ADCDAT, // Audio CODEC ADC Data
124 inout AUD_DACLRCK, // Audio CODEC DAC LR Clock
125 output AUD_DACDAT, // Audio CODEC DAC Data
126 inout AUD_BCLK, // Audio CODEC Bit-Stream Clock
127 output AUD_XCK, // Audio CODEC Chip Clock
128 //////////////////// TV Devoder ////////////////////////////
129 input [7:0] TD_DATA, // TV Decoder Data bus 8 bits
130 input TD_HS, // TV Decoder H_SYNC
131 input TD_VS, // TV Decoder V_SYNC
132 output TD_RESET, // TV Decoder Reset
133 //////////////////////// GPIO ////////////////////////////////
134 inout [35:0] GPIO_0, // GPIO Connection 0
135 inout [35:0] GPIO_1 // GPIO Connection 1
136 );
137
138 assign LCD_ON = 1'b1;
139 assign LCD_BLON = 1'b1;
140 assign TD_RESET = 1'b1;
141
142 // All inout port turn to tri-state
143 assign FL_DQ = 8'hzz;
144 assign SRAM_DQ = 16'hzzzz;
145 assign OTG_DATA = 16'hzzzz;
146 assign LCD_DATA = 8'hzz;
147 assign SD_DAT = 1'bz;
148 assign I2C_SDAT = 1'bz;
149 assign ENET_DATA = 16'hzzzz;
150 assign AUD_ADCLRCK = 1'bz;
151 assign AUD_DACLRCK = 1'bz;
152 assign AUD_BCLK = 1'bz;
153
154 // CCD
155 wire [9:0] CCD_DATA;
156 wire CCD_SDAT;
157 wire CCD_SCLK;
158 wire CCD_FLASH;
159 wire CCD_FVAL;
160 wire CCD_LVAL;
161 wire CCD_PIXCLK;
162 reg CCD_MCLK; // CCD Master Clock
163
164 wire [15:0] Read_DATA1;
165 wire [15:0] Read_DATA2;
166 wire VGA_CTRL_CLK;
167 wire AUD_CTRL_CLK;
168 wire [9:0] mCCD_DATA;
169 wire mCCD_DVAL;
170 wire mCCD_DVAL_d;
171 wire [10:0] X_Cont;
172 wire [10:0] Y_Cont;
173 wire [9:0] X_ADDR;
174 wire [31:0] Frame_Cont;
175 wire [9:0] mCCD_R;
176 wire [9:0] mCCD_G;
177 wire [9:0] mCCD_B;
178 wire DLY_RST_0;
179 wire DLY_RST_1;
180 wire DLY_RST_2;
181 wire Read;
182 reg [9:0] rCCD_DATA;
183 reg rCCD_LVAL;
184 reg rCCD_FVAL;
185 wire [9:0] sCCD_R;
186 wire [9:0] sCCD_G;
187 wire [9:0] sCCD_B;
188 wire sCCD_DVAL;
189
190 // For Sensor 1
191 assign CCD_DATA[0] = GPIO_1[0];
192 assign CCD_DATA[1] = GPIO_1[1];
193 assign CCD_DATA[2] = GPIO_1[5];
194 assign CCD_DATA[3] = GPIO_1[3];
195 assign CCD_DATA[4] = GPIO_1[2];
196 assign CCD_DATA[5] = GPIO_1[4];
197 assign CCD_DATA[6] = GPIO_1[6];
198 assign CCD_DATA[7] = GPIO_1[7];
199 assign CCD_DATA[8] = GPIO_1[8];
200 assign CCD_DATA[9] = GPIO_1[9];
201 assign GPIO_1[11] = CCD_MCLK;
202 assign CCD_FVAL = GPIO_1[13];
203 assign CCD_LVAL = GPIO_1[12];
204 assign CCD_PIXCLK = GPIO_1[10];
205
206 assign LEDR = SW;
207 assign LEDG = Y_Cont;
208 assign VGA_CTRL_CLK= CCD_MCLK;
209 assign VGA_CLK = ~CCD_MCLK;
210
211 always@(posedge CLOCK_50)
212 CCD_MCLK <= ~CCD_MCLK;
213
214 always@(posedge CCD_PIXCLK) begin
215 rCCD_DATA <= CCD_DATA;
216 rCCD_LVAL <= CCD_LVAL;
217 rCCD_FVAL <= CCD_FVAL;
218 end
219
220 VGA_Controller vga0 (
221 // Host Side
222 .oRequest(Read),
223 .iRed(Read_DATA1[9:0]),
224 .iGreen(Read_DATA1[9:0]),
225 .iBlue(Read_DATA1[9:0]),
226 // VGA Side
227 .oVGA_R(VGA_R),
228 .oVGA_G(VGA_G),
229 .oVGA_B(VGA_B),
230 .oVGA_H_SYNC(VGA_HS),
231 .oVGA_V_SYNC(VGA_VS),
232 .oVGA_SYNC(VGA_SYNC),
233 .oVGA_BLANK(VGA_BLANK),
234 // Control Signal
235 .iCLK(VGA_CTRL_CLK),
236 .iRST_N(DLY_RST_2)
237 );
238
239 Reset_Delay reset0 (
240 .iCLK(CLOCK_50),
241 .iRST(KEY[0]),
242 .oRST_0(DLY_RST_0),
243 .oRST_1(DLY_RST_1),
244 .oRST_2(DLY_RST_2)
245 );
246
247 CCD_Capture capture0 (
248 .oDATA(mCCD_DATA),
249 .oDVAL(mCCD_DVAL),
250 .oX_Cont(X_Cont),
251 .oY_Cont(Y_Cont),
252 .oFrame_Cont(Frame_Cont),
253 .iDATA(rCCD_DATA),
254 .iFVAL(rCCD_FVAL),
255 .iLVAL(rCCD_LVAL),
256 .iSTART(!KEY[3]),
257 .iEND(!KEY[2]),
258 .iCLK(CCD_PIXCLK),
259 .iRST(DLY_RST_1)
260 );
261
262 RAW2RGB rgb0 (
263 .oRed(mCCD_R),
264 .oGreen(mCCD_G),
265 .oBlue(mCCD_B),
266 .oDVAL(mCCD_DVAL_d),
267 .iX_Cont(X_Cont),
268 .iY_Cont(Y_Cont),
269 .iDATA(mCCD_DATA),
270 .iDVAL(mCCD_DVAL),
271 .iCLK(CCD_PIXCLK),
272 .iRST(DLY_RST_1)
273 );
274
275 SEG7_LUT_8 seg0 (
276 .oSEG0(HEX0),
277 .oSEG1(HEX1),
278 .oSEG2(HEX2),
279 .oSEG3(HEX3),
280 .oSEG4(HEX4),
281 .oSEG5(HEX5),
282 .oSEG6(HEX6),
283 .oSEG7(HEX7),
284 .iDIG(Frame_Cont)
285 );
286
287 Sdram_Control_4Port sdram0 (
288 // HOST Side
289 .REF_CLK(CLOCK_50),
290 .RESET_N(1'b1),
291 // FIFO Write Side 1
292 .WR1_DATA({6'h00, sCCD_G[9:0]}),
293 .WR1(sCCD_DVAL),
294 .WR1_ADDR(0),
295 .WR1_MAX_ADDR(640*512),
296 .WR1_LENGTH(9'h100),
297 .WR1_LOAD(!DLY_RST_0),
298 .WR1_CLK(CCD_PIXCLK),
299 // FIFO Read Side 1
300 .RD1_DATA(Read_DATA1),
301 .RD1(Read),
302 .RD1_ADDR(640*16),
303 .RD1_MAX_ADDR(640*496),
304 .RD1_LENGTH(9'h100),
305 .RD1_LOAD(!DLY_RST_0),
306 .RD1_CLK(VGA_CTRL_CLK),
307 // SDRAM Side
308 .SA(DRAM_ADDR),
309 .BA({DRAM_BA_1,DRAM_BA_0}),
310 .CS_N(DRAM_CS_N),
311 .CKE(DRAM_CKE),
312 .RAS_N(DRAM_RAS_N),
313 .CAS_N(DRAM_CAS_N),
314 .WE_N(DRAM_WE_N),
315 .DQ(DRAM_DQ),
316 .DQM({DRAM_UDQM,DRAM_LDQM}),
317 .SDR_CLK(DRAM_CLK)
318 );
319
320 I2C_CCD_Config ccd_config0 (
321 // Host Side
322 .iCLK(CLOCK_50),
323 .iRST_N(KEY[1]),
324 .iExposure(SW[15:0]),
325 // I2C Side
326 .I2C_SCLK(GPIO_1[14]),
327 .I2C_SDAT(GPIO_1[15])
328 );
329
330 Mirror_Col mirror0 (
331 // Input Side
332 .iCCD_R(mCCD_R),
333 .iCCD_G(mCCD_G),
334 .iCCD_B(mCCD_B),
335 .iCCD_DVAL(mCCD_DVAL_d),
336 .iCCD_PIXCLK(CCD_PIXCLK),
337 .iRST_N(DLY_RST_1),
338 // Output Side
339 .oCCD_R(sCCD_R),
340 .oCCD_G(sCCD_G),
341 .oCCD_B(sCCD_B),
342 .oCCD_DVAL(sCCD_DVAL)
343 );
344
345 endmodule
287行
// HOST Side
.REF_CLK(CLOCK_50),
.RESET_N(1'b1),
// FIFO Write Side 1
.WR1_DATA({6'h00, sCCD_G[9:0]}),
.WR1(sCCD_DVAL),
.WR1_ADDR(0),
.WR1_MAX_ADDR(640*512),
.WR1_LENGTH(9'h100),
.WR1_LOAD(!DLY_RST_0),
.WR1_CLK(CCD_PIXCLK),
// FIFO Read Side 1
.RD1_DATA(Read_DATA1),
.RD1(Read),
.RD1_ADDR(640*16),
.RD1_MAX_ADDR(640*496),
.RD1_LENGTH(9'h100),
.RD1_LOAD(!DLY_RST_0),
.RD1_CLK(VGA_CTRL_CLK),
// SDRAM Side
.SA(DRAM_ADDR),
.BA({DRAM_BA_1,DRAM_BA_0}),
.CS_N(DRAM_CS_N),
.CKE(DRAM_CKE),
.RAS_N(DRAM_RAS_N),
.CAS_N(DRAM_CAS_N),
.WE_N(DRAM_WE_N),
.DQ(DRAM_DQ),
.DQM({DRAM_UDQM,DRAM_LDQM}),
.SDR_CLK(DRAM_CLK)
);
原來的DE2_CCD是使用2 read 2 write,因為現在SDRAM只要存灰階就好, 所以只需1 read 1 write就好,這樣不只省了空間,還節省了SDRAM的頻寬,為什麼不能省2/3 SDRAM空間呢? 因為SDRAM的WR1_DATA為16 bit,雖然灰階只有10 bit,但剩下的6 bit即使用不到,也是補0而已,所以實際上只能省一半空間。
220行
// Host Side
.oRequest(Read),
.iRed(Read_DATA1[9:0]),
.iGreen(Read_DATA1[9:0]),
.iBlue(Read_DATA1[9:0]),
// VGA Side
.oVGA_R(VGA_R),
.oVGA_G(VGA_G),
.oVGA_B(VGA_B),
.oVGA_H_SYNC(VGA_HS),
.oVGA_V_SYNC(VGA_VS),
.oVGA_SYNC(VGA_SYNC),
.oVGA_BLANK(VGA_BLANK),
// Control Signal
.iCLK(VGA_CTRL_CLK),
.iRST_N(DLY_RST_2)
);
最後輸入VGA Controller的RGB都只能用Read_Data1,也就是RGB全部用G來代替。
Method 2:
在SDRAM之後
DE2_CCD.v / Verilog
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3
4 Filename : DE2_CCD.v
5 Compiler : Quartus II 7.2 SP3
6 Description : Demo how to use 130m CMOS to make gray after SDRAM on DE2
7 Release : 08/23/2008 1.0
8 */
9
10 module DE2_CCD (
11 //////////////////////// Clock Input ////////////////////////
12 input CLOCK_27, // 27 MHz
13 input CLOCK_50, // 50 MHz
14 input EXT_CLOCK, // External Clock
15 //////////////////////// Push Button ////////////////////////
16 input [3:0] KEY, // Pushbutton[3:0]
17 //////////////////////// DPDT Switch ////////////////////////
18 input [17:0] SW, // Toggle Switch[17:0]
19 //////////////////////// 7-SEG Dispaly ////////////////////////
20 output [6:0] HEX0, // Seven Segment Digit 0
21 output [6:0] HEX1, // Seven Segment Digit 1
22 output [6:0] HEX2, // Seven Segment Digit 2
23 output [6:0] HEX3, // Seven Segment Digit 3
24 output [6:0] HEX4, // Seven Segment Digit 4
25 output [6:0] HEX5, // Seven Segment Digit 5
26 output [6:0] HEX6, // Seven Segment Digit 6
27 output [6:0] HEX7, // Seven Segment Digit 7
28 //////////////////////////// LED ////////////////////////////
29 output [8:0] LEDG, // LED Green[8:0]
30 output [17:0] LEDR, // LED Red[17:0]
31 //////////////////////////// UART ////////////////////////////
32 output UART_TXD, // UART Transmitter
33 input UART_RXD, // UART Receiver
34 //////////////////////////// IRDA ////////////////////////////
35 output IRDA_TXD, // IRDA Transmitter
36 input IRDA_RXD, // IRDA Receiver
37 /////////////////////// SDRAM Interface ////////////////////////
38 inout [15:0] DRAM_DQ, // SDRAM Data bus 16 Bits
39 output [11:0] DRAM_ADDR, // SDRAM Address bus 12 Bits
40 output DRAM_LDQM, // SDRAM Low-byte Data Mask
41 output DRAM_UDQM, // SDRAM High-byte Data Mask
42 output DRAM_WE_N, // SDRAM Write Enable
43 output DRAM_CAS_N, // SDRAM Column Address Strobe
44 output DRAM_RAS_N, // SDRAM Row Address Strobe
45 output DRAM_CS_N, // SDRAM Chip Select
46 output DRAM_BA_0, // SDRAM Bank Address 0
47 output DRAM_BA_1, // SDRAM Bank Address 0
48 output DRAM_CLK, // SDRAM Clock
49 output DRAM_CKE, // SDRAM Clock Enable
50 //////////////////////// Flash Interface ////////////////////////
51 inout [7:0] FL_DQ, // FLASH Data bus 8 Bits
52 output [21:0] FL_ADDR, // FLASH Address bus 22 Bits
53 output FL_WE_N, // FLASH Write Enable
54 output FL_RST_N, // FLASH Reset
55 output FL_OE_N, // FLASH Output Enable
56 output FL_CE_N, // FLASH Chip Enable
57 //////////////////////// SRAM Interface ////////////////////////
58 inout [15:0] SRAM_DQ, // SRAM Data bus 16 Bits
59 output [17:0] SRAM_ADDR, // SRAM Address bus 18 Bits
60 output SRAM_UB_N, // SRAM High-byte Data Mask
61 output SRAM_LB_N, // SRAM Low-byte Data Mask
62 output SRAM_WE_N, // SRAM Write Enable
63 output SRAM_CE_N, // SRAM Chip Enable
64 output SRAM_OE_N, // SRAM Output Enable
65 //////////////////// ISP1362 Interface ////////////////////////
66 inout [15:0] OTG_DATA, // ISP1362 Data bus 16 Bits
67 output [1:0] OTG_ADDR, // ISP1362 Address 2 Bits
68 output OTG_CS_N, // ISP1362 Chip Select
69 output OTG_RD_N, // ISP1362 Write
70 output OTG_WR_N, // ISP1362 Read
71 output OTG_RST_N, // ISP1362 Reset
72 output OTG_FSPEED, // USB Full Speed, 0 = Enable, Z = Disable
73 output OTG_LSPEED, // USB Low Speed, 0 = Enable, Z = Disable
74 input OTG_INT0, // ISP1362 Interrupt 0
75 input OTG_INT1, // ISP1362 Interrupt 1
76 input OTG_DREQ0, // ISP1362 DMA Request 0
77 input OTG_DREQ1, // ISP1362 DMA Request 1
78 output OTG_DACK0_N, // ISP1362 DMA Acknowledge 0
79 output OTG_DACK1_N, // ISP1362 DMA Acknowledge 1
80 //////////////////// LCD Module 16X2 ////////////////////////////
81 inout [7:0] LCD_DATA, // LCD Data bus 8 bits
82 output LCD_ON, // LCD Power ON/OFF
83 output LCD_BLON, // LCD Back Light ON/OFF
84 output LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read
85 output LCD_EN, // LCD Enable
86 output LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data
87 //////////////////// SD Card Interface ////////////////////////
88 inout SD_DAT, // SD Card Data
89 inout SD_DAT3, // SD Card Data 3
90 inout SD_CMD, // SD Card Command Signal
91 output SD_CLK, // SD Card Clock
92 //////////////////////// I2C ////////////////////////////////
93 inout I2C_SDAT, // I2C Data
94 output I2C_SCLK, // I2C Clock
95 //////////////////////// PS2 ////////////////////////////////
96 input PS2_DAT, // PS2 Data
97 input PS2_CLK, // PS2 Clock
98 //////////////////// USB JTAG link ////////////////////////////
99 input TDI, // CPLD -> FPGA (data in)
100 input TCK, // CPLD -> FPGA (clk)
101 input TCS, // CPLD -> FPGA (CS)
102 output TDO, // FPGA -> CPLD (data out)
103 //////////////////////// VGA ////////////////////////////
104 output VGA_CLK, // VGA Clock
105 output VGA_HS, // VGA H_SYNC
106 output VGA_VS, // VGA V_SYNC
107 output VGA_BLANK, // VGA BLANK
108 output VGA_SYNC, // VGA SYNC
109 output [9:0] VGA_R, // VGA Red[9:0]
110 output [9:0] VGA_G, // VGA Green[9:0]
111 output [9:0] VGA_B, // VGA Blue[9:0]
112 //////////////// Ethernet Interface ////////////////////////////
113 inout [15:0] ENET_DATA, // DM9000A DATA bus 16Bits
114 output ENET_CMD, // DM9000A Command/Data Select, 0 = Command, 1 = Data
115 output ENET_CS_N, // DM9000A Chip Select
116 output ENET_WR_N, // DM9000A Write
117 output ENET_RD_N, // DM9000A Read
118 output ENET_RST_N, // DM9000A Reset
119 input ENET_INT, // DM9000A Interrupt
120 output ENET_CLK, // DM9000A Clock 25 MHz
121 //////////////////// Audio CODEC ////////////////////////////
122 inout AUD_ADCLRCK, // Audio CODEC ADC LR Clock
123 input AUD_ADCDAT, // Audio CODEC ADC Data
124 inout AUD_DACLRCK, // Audio CODEC DAC LR Clock
125 output AUD_DACDAT, // Audio CODEC DAC Data
126 inout AUD_BCLK, // Audio CODEC Bit-Stream Clock
127 output AUD_XCK, // Audio CODEC Chip Clock
128 //////////////////// TV Devoder ////////////////////////////
129 input [7:0] TD_DATA, // TV Decoder Data bus 8 bits
130 input TD_HS, // TV Decoder H_SYNC
131 input TD_VS, // TV Decoder V_SYNC
132 output TD_RESET, // TV Decoder Reset
133 //////////////////////// GPIO ////////////////////////////////
134 inout [35:0] GPIO_0, // GPIO Connection 0
135 inout [35:0] GPIO_1 // GPIO Connection 1
136 );
137
138 assign LCD_ON = 1'b1;
139 assign LCD_BLON = 1'b1;
140 assign TD_RESET = 1'b1;
141
142 // All inout port turn to tri-state
143 assign FL_DQ = 8'hzz;
144 assign SRAM_DQ = 16'hzzzz;
145 assign OTG_DATA = 16'hzzzz;
146 assign LCD_DATA = 8'hzz;
147 assign SD_DAT = 1'bz;
148 assign I2C_SDAT = 1'bz;
149 assign ENET_DATA = 16'hzzzz;
150 assign AUD_ADCLRCK = 1'bz;
151 assign AUD_DACLRCK = 1'bz;
152 assign AUD_BCLK = 1'bz;
153
154 // CCD
155 wire [9:0] CCD_DATA;
156 wire CCD_SDAT;
157 wire CCD_SCLK;
158 wire CCD_FLASH;
159 wire CCD_FVAL;
160 wire CCD_LVAL;
161 wire CCD_PIXCLK;
162 reg CCD_MCLK; // CCD Master Clock
163
164 wire [15:0] Read_DATA1;
165 wire [15:0] Read_DATA2;
166 wire VGA_CTRL_CLK;
167 wire AUD_CTRL_CLK;
168 wire [9:0] mCCD_DATA;
169 wire mCCD_DVAL;
170 wire mCCD_DVAL_d;
171 wire [10:0] X_Cont;
172 wire [10:0] Y_Cont;
173 wire [9:0] X_ADDR;
174 wire [31:0] Frame_Cont;
175 wire [9:0] mCCD_R;
176 wire [9:0] mCCD_G;
177 wire [9:0] mCCD_B;
178 wire DLY_RST_0;
179 wire DLY_RST_1;
180 wire DLY_RST_2;
181 wire Read;
182 reg [9:0] rCCD_DATA;
183 reg rCCD_LVAL;
184 reg rCCD_FVAL;
185 wire [9:0] sCCD_R;
186 wire [9:0] sCCD_G;
187 wire [9:0] sCCD_B;
188 wire sCCD_DVAL;
189
190 // For Sensor 1
191 assign CCD_DATA[0] = GPIO_1[0];
192 assign CCD_DATA[1] = GPIO_1[1];
193 assign CCD_DATA[2] = GPIO_1[5];
194 assign CCD_DATA[3] = GPIO_1[3];
195 assign CCD_DATA[4] = GPIO_1[2];
196 assign CCD_DATA[5] = GPIO_1[4];
197 assign CCD_DATA[6] = GPIO_1[6];
198 assign CCD_DATA[7] = GPIO_1[7];
199 assign CCD_DATA[8] = GPIO_1[8];
200 assign CCD_DATA[9] = GPIO_1[9];
201 assign GPIO_1[11] = CCD_MCLK;
202 assign CCD_FVAL = GPIO_1[13];
203 assign CCD_LVAL = GPIO_1[12];
204 assign CCD_PIXCLK = GPIO_1[10];
205
206 assign LEDR = SW;
207 assign LEDG = Y_Cont;
208 assign VGA_CTRL_CLK= CCD_MCLK;
209 assign VGA_CLK = ~CCD_MCLK;
210
211 always@(posedge CLOCK_50)
212 CCD_MCLK <= ~CCD_MCLK;
213
214 always@(posedge CCD_PIXCLK) begin
215 rCCD_DATA <= CCD_DATA;
216 rCCD_LVAL <= CCD_LVAL;
217 rCCD_FVAL <= CCD_FVAL;
218 end
219
220 VGA_Controller vga0 (
221 // Host Side
222 .oRequest(Read),
223 .iRed({Read_DATA1[14:10],Read_DATA2[14:10]}),
224 .iGreen({Read_DATA1[14:10],Read_DATA2[14:10]}),
225 .iBlue({Read_DATA1[14:10],Read_DATA2[14:10]}),
226 // VGA Side
227 .oVGA_R(VGA_R),
228 .oVGA_G(VGA_G),
229 .oVGA_B(VGA_B),
230 .oVGA_H_SYNC(VGA_HS),
231 .oVGA_V_SYNC(VGA_VS),
232 .oVGA_SYNC(VGA_SYNC),
233 .oVGA_BLANK(VGA_BLANK),
234 // Control Signal
235 .iCLK(VGA_CTRL_CLK),
236 .iRST_N(DLY_RST_2)
237 );
238
239 Reset_Delay reset0 (
240 .iCLK(CLOCK_50),
241 .iRST(KEY[0]),
242 .oRST_0(DLY_RST_0),
243 .oRST_1(DLY_RST_1),
244 .oRST_2(DLY_RST_2)
245 );
246
247 CCD_Capture capture0 (
248 .oDATA(mCCD_DATA),
249 .oDVAL(mCCD_DVAL),
250 .oX_Cont(X_Cont),
251 .oY_Cont(Y_Cont),
252 .oFrame_Cont(Frame_Cont),
253 .iDATA(rCCD_DATA),
254 .iFVAL(rCCD_FVAL),
255 .iLVAL(rCCD_LVAL),
256 .iSTART(!KEY[3]),
257 .iEND(!KEY[2]),
258 .iCLK(CCD_PIXCLK),
259 .iRST(DLY_RST_1)
260 );
261
262 RAW2RGB rgb0 (
263 .oRed(mCCD_R),
264 .oGreen(mCCD_G),
265 .oBlue(mCCD_B),
266 .oDVAL(mCCD_DVAL_d),
267 .iX_Cont(X_Cont),
268 .iY_Cont(Y_Cont),
269 .iDATA(mCCD_DATA),
270 .iDVAL(mCCD_DVAL),
271 .iCLK(CCD_PIXCLK),
272 .iRST(DLY_RST_1)
273 );
274
275 SEG7_LUT_8 seg0 (
276 .oSEG0(HEX0),
277 .oSEG1(HEX1),
278 .oSEG2(HEX2),
279 .oSEG3(HEX3),
280 .oSEG4(HEX4),
281 .oSEG5(HEX5),
282 .oSEG6(HEX6),
283 .oSEG7(HEX7),
284 .iDIG(Frame_Cont)
285 );
286
287 Sdram_Control_4Port sdram0 (
288 // HOST Side
289 .REF_CLK(CLOCK_50),
290 .RESET_N(1'b1),
291 // FIFO Write Side 1
292 .WR1_DATA({sCCD_G[9:5], sCCD_B[9:0]}),
293 .WR1(sCCD_DVAL),
294 .WR1_ADDR(0),
295 .WR1_MAX_ADDR(640*512),
296 .WR1_LENGTH(9'h100),
297 .WR1_LOAD(!DLY_RST_0),
298 .WR1_CLK(CCD_PIXCLK),
299 // FIFO Write Side 2
300 .WR2_DATA({sCCD_G[4:0], sCCD_R[9:0]}),
301 .WR2(sCCD_DVAL),
302 .WR2_ADDR(22'h100000),
303 .WR2_MAX_ADDR(22'h100000+640*512),
304 .WR2_LENGTH(9'h100),
305 .WR2_LOAD(!DLY_RST_0),
306 .WR2_CLK(CCD_PIXCLK),
307 // FIFO Read Side 1
308 .RD1_DATA(Read_DATA1),
309 .RD1(Read),
310 .RD1_ADDR(640*16),
311 .RD1_MAX_ADDR(640*496),
312 .RD1_LENGTH(9'h100),
313 .RD1_LOAD(!DLY_RST_0),
314 .RD1_CLK(VGA_CTRL_CLK),
315 // FIFO Read Side 2
316 .RD2_DATA(Read_DATA2),
317 .RD2(Read),
318 .RD2_ADDR(22'h100000+640*16),
319 .RD2_MAX_ADDR(22'h100000+640*496),
320 .RD2_LENGTH(9'h100),
321 .RD2_LOAD(!DLY_RST_0),
322 .RD2_CLK(VGA_CTRL_CLK),
323 // SDRAM Side
324 .SA(DRAM_ADDR),
325 .BA({DRAM_BA_1,DRAM_BA_0}),
326 .CS_N(DRAM_CS_N),
327 .CKE(DRAM_CKE),
328 .RAS_N(DRAM_RAS_N),
329 .CAS_N(DRAM_CAS_N),
330 .WE_N(DRAM_WE_N),
331 .DQ(DRAM_DQ),
332 .DQM({DRAM_UDQM,DRAM_LDQM}),
333 .SDR_CLK(DRAM_CLK)
334 );
335
336 I2C_CCD_Config ccd_config0 (
337 // Host Side
338 .iCLK(CLOCK_50),
339 .iRST_N(KEY[1]),
340 .iExposure(SW[15:0]),
341 // I2C Side
342 .I2C_SCLK(GPIO_1[14]),
343 .I2C_SDAT(GPIO_1[15])
344 );
345
346 Mirror_Col mirror0 (
347 // Input Side
348 .iCCD_R(mCCD_R),
349 .iCCD_G(mCCD_G),
350 .iCCD_B(mCCD_B),
351 .iCCD_DVAL(mCCD_DVAL_d),
352 .iCCD_PIXCLK(CCD_PIXCLK),
353 .iRST_N(DLY_RST_1),
354 // Output Side
355 .oCCD_R(sCCD_R),
356 .oCCD_G(sCCD_G),
357 .oCCD_B(sCCD_B),
358 .oCCD_DVAL(sCCD_DVAL)
359 );
360
361 endmodule
220行
// Host Side
.oRequest(Read),
.iRed({Read_DATA1[14:10],Read_DATA2[14:10]}),
.iGreen({Read_DATA1[14:10],Read_DATA2[14:10]}),
.iBlue({Read_DATA1[14:10],Read_DATA2[14:10]}),
// VGA Side
.oVGA_R(VGA_R),
.oVGA_G(VGA_G),
.oVGA_B(VGA_B),
.oVGA_H_SYNC(VGA_HS),
.oVGA_V_SYNC(VGA_VS),
.oVGA_SYNC(VGA_SYNC),
.oVGA_BLANK(VGA_BLANK),
// Control Signal
.iCLK(VGA_CTRL_CLK),
.iRST_N(DLY_RST_2)
);
在SDRAM之後處理比較簡單,{Read_DATA1[14:10],Read_DATA2[14:10]}為G的資料,只要將這個資料也送進VGA controller的iRed與iBlue即可,也就是本來該送R、B的資料,現在全部用G代替。
完整程式碼下載
DE2_CCD_gray_before_SDRAM.7z
DE2_CCD_gray_after_SDRAM.7z
Conclusion
以上兩種方式最後的結果完全一樣,都能在real time產生灰階影像。
這個例子告訴我們,硬體實現演算法時,不可能如軟體一樣一成不變,可能必須做適當的修改以利硬體實現,也看見了在DE2平台,以DE2_CCD範例為基礎,可以在SDRAM的前後加上演算法做影像處理。
DE2-70該如何real time產生灰階影像呢?原理跟架構與DE2類似,不過仍有小地方值得討論,我將在明天另外討論DE2-70,接下來將以此為基礎,討論如何在DE2平台用硬體實現real time的Sobel Edge Detection演算法。
See Also
(原創) 如何將CMOS彩色影像轉換成灰階影像? (SOC) (DE2)
(原創) 如何Real Time產生灰階影像? (SOC) (DE2-70) (TRDB-D5M)
(原創) 如何實現Real Time的Sobel Edge Detector? (SOC) (Verilog) (Image Processing) (DE2-70) (TRDB-D5M)
(原創) 如何實現Real Time的Sobel Edge Detector? (SOC) (Verilog) (Image Processing) (DE2) (TRDB-DC2)