(原創) 如何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轉灰階演算法呢?基本上這已經可以發論文討論了,一般來說,較讓大部分人所接受的公式是

Gray = 0.299 * R + 0.587 * G + 0.114 * B


這牽涉到浮點運算,不要說硬體難實現,光用C去寫,執行速度也很不理想,所以才會有人乾脆用(R+G+B) /3來做。若要在硬體實現,勢必再做一些簡化。

注意到R、G、B的權重嗎?G的權重幾乎是R的2倍,B的權重的5倍,所以真正決定灰階程度的關鍵在於G,而R、B的影響較不顯著,所以乾脆就用G來代表灰階,這種方式最有利於硬體實現。

硬體的實現

vga00

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

  1 /* 
  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行

Sdram_Control_4Port sdram0  (
 
//  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行

VGA_Controller  vga0 (
 
//  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

  1 /* 
  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行

VGA_Controller  vga0 (
 
//  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)  

posted on 2008-08-23 21:44  真 OO无双  阅读(9893)  评论(13编辑  收藏  举报

导航