(原創) 如何將CMOS影像以RGB16的方式存入SDRAM? (SOC) (DE2-70) (TRDB-D5M) (TRDB-LTM)

Abstract
在數位視訊系統中,SDRAM扮演CMOS與LCD之間frame buffer的腳色,但若SDRAM另用他用,只好將RGB以16 bit方式存入SDRAM,將節省下來的空間做其他用途。

Introduction
使用環境:Quartus II 8.0 SP1 + DE2-70 (Cyclone II EP2C70F896C6N) + TRDB-D5M + TRDB-LTM

以RGB16(R5G6B5)的方式存入SDRAM的方式並不是我所創,在友晶提供的DE2_CCD_detect範例中,因為要做motion detection,要用前後兩個frame的資料做比對,所以整個SDRAM不能全部做成CMOS與VGA的frame buffer,必須有一塊區域存前一個frame的資料,而DE2又只有一顆8MB SDRAM,所以2個write port與2個read port不能全部用盡,CMOS與VGA只能占用1個write port與read port,而SDRAM的寬度為16 bit,所以只能以RGB16存進SDRAM。

或許你會有疑問,以RGB16來處理,不會失真嗎?理論上是會失真,不過由於是取高5 bit處理,所以還可接受,以下是用RGB16與RGB32結果的比較

左側為RGB16、右側為RGB32

de2-70_ltm_rgb16 de2-70_ltm_rgb32

兩張圖是有一點點差距,不過大體上來說還可以接受,若你用的是DE2,因為只有一顆8MB SDRAM,就只能靠RGB16的方式,才能讓SDRAM還能放其他的資料,而不讓2個write port與2個read port全被RGB32占滿,當然若你用的是DE2-70,因為有兩顆SDRAM,就沒這種問題。

網友就剛好遇到需要用RGB16的狀況,不過它的環境是DE2 + TRDB-D5M + TRDB-LTM,但因為我用的是DE2-70的三合一套件,也就是DE2-70 + TRDB-D5M + TRDB-LTM,所以我只能用DE2-70模擬DE2只有一顆SDRAM的狀況,然後使用RGB16的方式存入SDRAM。

Top Module部分
DE2_70.v / Verilog

  1 /* 
  2 (C) OOMusou 2008 http://oomusou.cnblogs.com
  3 
  4 Filename    : DE2_70.v
  5 Compiler    : Quartus II 8.0 SP1
  6 Description : Demo how to use TRDB-D5M with LTM on DE2-70 with RGB16
  7 Release     : 10/24/2008 1.0
  8 */
  9 
10 module DE2_70 (
11   //////////////////////// Clock Input ////////////////////////
12   input          iCLK_28,           // 28.63636 MHz
13   input          iCLK_50,           // 50 MHz
14   input          iCLK_50_2,         // 50 MHz
15   input          iCLK_50_3,         // 50 MHz
16   input          iCLK_50_4,         // 50 MHz
17   input          iEXT_CLOCK,        // External Clock
18   //////////////////////// Push Button ////////////////////////
19   input  [3:0]   iKEY,              // Pushbutton[3:0]
20   //////////////////////// DPDT Switch ////////////////////////
21   input  [17:0]  iSW,               // Toggle Switch[17:0]
22   //////////////////////// 7-SEG Dispaly ////////////////////////
23   output [6:0]   oHEX0_D,           // Seven Segment Digit 0
24   output         oHEX0_DP,          // Seven Segment Digit 0 decimal point
25   output [6:0]   oHEX1_D,           // Seven Segment Digit 1
26   output         oHEX1_DP,          // Seven Segment Digit 1 decimal point
27   output [6:0]   oHEX2_D,           // Seven Segment Digit 2
28   output         oHEX2_DP,          // Seven Segment Digit 2 decimal point
29   output [6:0]   oHEX3_D,           // Seven Segment Digit 3
30   output         oHEX3_DP,          // Seven Segment Digit 3 decimal point
31   output [6:0]   oHEX4_D,           // Seven Segment Digit 4
32   output         oHEX4_DP,          // Seven Segment Digit 4 decimal point
33   output [6:0]   oHEX5_D,           // Seven Segment Digit 5
34   output         oHEX5_DP,          // Seven Segment Digit 5 decimal point
35   output [6:0]   oHEX6_D,           // Seven Segment Digit 6
36   output         oHEX6_DP,          // Seven Segment Digit 6 decimal point
37   output [6:0]   oHEX7_D,           // Seven Segment Digit 7
38   output         oHEX7_DP,          // Seven Segment Digit 7 decimal point
39   //////////////////////////// LED ////////////////////////////
40   output [8:0]   oLEDG,             // LED Green[8:0]
41   output [17:0]  oLEDR,             // LED Red[17:0]
42   //////////////////////////// UART ////////////////////////////
43   output         oUART_TXD,         // UART Transmitter
44   input          iUART_RXD,         // UART Receiver
45   output         oUART_CTS,         // UART Clear To Send
46   input          iUART_RTS,         // UART Requst To Send
47   //////////////////////////// IRDA ////////////////////////////
48   output         oIRDA_TXD,         // IRDA Transmitter
49   input          iIRDA_RXD,         // IRDA Receiver
50   /////////////////////// SDRAM Interface ////////////////////////
51   inout   [31:0] DRAM_DQ,           // SDRAM Data bus 32 Bits
52   output  [12:0] oDRAM0_A,          // SDRAM0 Address bus 13 Bits
53   output  [12:0] oDRAM1_A,          // SDRAM1 Address bus 13 Bits
54   output         oDRAM0_LDQM0,      // SDRAM0 Low-byte Data Mask
55   output         oDRAM1_LDQM0,      // SDRAM1 Low-byte Data Mask
56   output         oDRAM0_UDQM1,      // SDRAM0 High-byte Data Mask
57   output         oDRAM1_UDQM1,      // SDRAM1 High-byte Data Mask
58   output         oDRAM0_WE_N,       // SDRAM0 Write Enable
59   output         oDRAM1_WE_N,       // SDRAM1 Write Enable
60   output         oDRAM0_CAS_N,      // SDRAM0 Column Address Strobe
61   output         oDRAM1_CAS_N,      // SDRAM1 Column Address Strobe
62   output         oDRAM0_RAS_N,      // SDRAM0 Row Address Strobe
63   output         oDRAM1_RAS_N,      // SDRAM1 Row Address Strobe
64   output         oDRAM0_CS_N,       // SDRAM0 Chip Select
65   output         oDRAM1_CS_N,       // SDRAM1 Chip Select
66   output  [1:0]  oDRAM0_BA,         // SDRAM0 Bank Address
67   output  [1:0]  oDRAM1_BA,         // SDRAM1 Bank Address
68   output         oDRAM0_CLK,        // SDRAM0 Clock
69   output         oDRAM1_CLK,        // SDRAM1 Clock
70   output         oDRAM0_CKE,        // SDRAM0 Clock Enable
71   output         oDRAM1_CKE,        // SDRAM1 Clock Enable
72   //////////////////////// Flash Interface ////////////////////////
73   inout   [14:0] FLASH_DQ,          // FLASH Data bus 15 Bits (0 to 14)
74   inout          FLASH_DQ15_AM1,    // FLASH Data bus Bit 15 or Address A-1
75   output  [21:0] oFLASH_A,          // FLASH Address bus 26 Bits
76   output         oFLASH_WE_N,       // FLASH Write Enable
77   output         oFLASH_RST_N,      // FLASH Reset
78   output         oFLASH_WP_N,       // FLASH Write Protect /Programming Acceleration
79   input          iFLASH_RY_N,       // FLASH Ready/Busy output
80   output         oFLASH_BYTE_N,     // FLASH Byte/Word Mode Configuration
81   output         oFLASH_OE_N,       // FLASH Output Enable
82   output         oFLASH_CE_N,       // FLASH Chip Enable
83   //////////////////////// SRAM Interface ////////////////////////
84   inout   [31:0] SRAM_DQ,           // SRAM Data Bus 32 Bits
85   inout   [3:0]  SRAM_DPA,          // SRAM Parity Data Bus
86   output  [18:0] oSRAM_A,           // SRAM Address bus 21 Bits
87   output         oSRAM_ADSC_N,      // SRAM Controller Address Status    
88   output         oSRAM_ADSP_N,      // SRAM Processor Address Status
89   output         oSRAM_ADV_N,       // SRAM Burst Address Advance
90   output  [3:0]  oSRAM_BE_N,        // SRAM Byte Write Enable
91   output         oSRAM_CE1_N,       // SRAM Chip Enable
92   output         oSRAM_CE2,         // SRAM Chip Enable
93   output         oSRAM_CE3_N,       // SRAM Chip Enable
94   output         oSRAM_CLK,         // SRAM Clock
95   output         oSRAM_GW_N,        // SRAM Global Write Enable
96   output         oSRAM_OE_N,        // SRAM Output Enable
97   output         oSRAM_WE_N,        // SRAM Write Enable
98   //////////////////// ISP1362 Interface ////////////////////////
99   inout   [15:0] OTG_D,             // ISP1362 Data bus 16 Bits
100   output  [1:0]  oOTG_A,            // ISP1362 Address 2 Bits
101   output         oOTG_CS_N,         // ISP1362 Chip Select
102   output         oOTG_OE_N,         // ISP1362 Read
103   output         oOTG_WE_N,         // ISP1362 Write
104   output         oOTG_RESET_N,      // ISP1362 Reset
105   inout          OTG_FSPEED,        // USB Full Speed,    0 = Enable, Z = Disable
106   inout          OTG_LSPEED,        // USB Low Speed,     0 = Enable, Z = Disable
107   input          iOTG_INT0,         // ISP1362 Interrupt 0
108   input          iOTG_INT1,         // ISP1362 Interrupt 1
109   input          iOTG_DREQ0,        // ISP1362 DMA Request 0
110   input          iOTG_DREQ1,        // ISP1362 DMA Request 1
111   output         oOTG_DACK0_N,      // ISP1362 DMA Acknowledge 0
112   output         oOTG_DACK1_N,      // ISP1362 DMA Acknowledge 1
113   //////////////////// LCD Module 16X2 ////////////////////////////
114   inout   [7:0]  LCD_D,             // LCD Data bus 8 bits
115   output         oLCD_ON,           // LCD Power ON/OFF
116   output         oLCD_BLON,         // LCD Back Light ON/OFF
117   output         oLCD_RW,           // LCD Read/Write Select, 0 = Write, 1 = Read
118   output         oLCD_EN,           // LCD Enable
119   output         oLCD_RS,           // LCD Command/Data Select, 0 = Command, 1 = Data
120   //////////////////// SD Card Interface ////////////////////////
121   inout          SD_DAT,            // SD Card Data
122   inout          SD_DAT3,           // SD Card Data 3
123   inout          SD_CMD,            // SD Card Command Signal
124   output         oSD_CLK,           // SD Card Clock
125   //////////////////////// I2C ////////////////////////////////
126   inout          I2C_SDAT,          // I2C Data
127   output         oI2C_SCLK,         // I2C Clock
128   //////////////////////// PS2 ////////////////////////////////
129   inout          PS2_KBDAT,         // PS2 Keyboard Data
130   inout          PS2_KBCLK,         // PS2 Keyboard Clock
131   inout          PS2_MSDAT,         // PS2 Mouse Data
132   inout          PS2_MSCLK,         // PS2 Mouse Clock
133   //////////////////////// VGA ////////////////////////////
134   output         oVGA_CLOCK,        // VGA Clock
135   output         oVGA_HS,           // VGA H_SYNC
136   output         oVGA_VS,           // VGA V_SYNC
137   output         oVGA_BLANK_N,      // VGA BLANK
138   output         oVGA_SYNC_N,       // VGA SYNC
139   output  [9:0]  oVGA_R,            // VGA Red[9:0]
140   output  [9:0]  oVGA_G,            // VGA Green[9:0]
141   output  [9:0]  oVGA_B,            // VGA Blue[9:0]
142   //////////////// Ethernet Interface ////////////////////////////
143   inout   [15:0] ENET_D,            // DM9000A DATA bus 16Bits
144   output         oENET_CMD,         // DM9000A Command/Data Select, 0 = Command, 1 = Data
145   output         oENET_CS_N,        // DM9000A Chip Select
146   output         oENET_IOW_N,       // DM9000A Write
147   output         oENET_IOR_N,       // DM9000A Read
148   output         oENET_RESET_N,     // DM9000A Reset
149   input          iENET_INT,         // DM9000A Interrupt
150   output         oENET_CLK,         // DM9000A Clock 25 MHz
151   //////////////////// Audio CODEC  ////////////////////////////
152   inout          AUD_ADCLRCK,       // Audio CODEC ADC LR Clock
153   input          iAUD_ADCDAT,       // Audio CODEC ADC Data
154   inout          AUD_DACLRCK,       // Audio CODEC DAC LR Clock
155   output         oAUD_DACDAT,       // Audio CODEC DAC Data
156   inout          AUD_BCLK,          // Audio CODEC Bit-Stream Clock
157   output         oAUD_XCK,          // Audio CODEC Chip Clock
158   //////////////////// TV Devoder   ////////////////////////////
159   input          iTD1_CLK27,        // TV Decoder1 Line_Lock Output Clock
160   input   [7:0]  iTD1_D,            // TV Decoder1 Data bus 8 bits
161   input          iTD1_HS,           // TV Decoder1 H_SYNC
162   input          iTD1_VS,           // TV Decoder1 V_SYNC
163   output         oTD1_RESET_N,      // TV Decoder1 Reset
164   input          iTD2_CLK27,        // TV Decoder2 Line_Lock Output Clock        
165   input   [7:0]  iTD2_D,            // TV Decoder2 Data bus 8 bits
166   input          iTD2_HS,           // TV Decoder2 H_SYNC
167   input          iTD2_VS,           // TV Decoder2 V_SYNC
168   output         oTD2_RESET_N,      // TV Decoder2 Reset
169   //////////////////////// GPIO ////////////////////////////////
170   inout   [31:0] GPIO_0,            // GPIO Connection 0 I/O
171   input          GPIO_CLKIN_N0,     // GPIO Connection 0 Clock Input 0
172   input          GPIO_CLKIN_P0,     // GPIO Connection 0 Clock Input 1
173   inout          GPIO_CLKOUT_N0,    // GPIO Connection 0 Clock Output 0
174   inout          GPIO_CLKOUT_P0,    // GPIO Connection 0 Clock Output 1
175   inout   [31:0] GPIO_1,            // GPIO Connection 1 I/O
176   input          GPIO_CLKIN_N1,     // GPIO Connection 1 Clock Input 0
177   input          GPIO_CLKIN_P1,     // GPIO Connection 1 Clock Input 1
178   inout          GPIO_CLKOUT_N1,    // GPIO Connection 1 Clock Output 0
179   inout          GPIO_CLKOUT_P1     // GPIO Connection 1 Clock Output 1
180 );
181 
182 //  CCD
183 wire  [11:0]  CCD_DATA;
184 wire          CCD_SDAT;
185 wire          CCD_SCLK;
186 wire          CCD_FLASH;
187 wire          CCD_FVAL;
188 wire          CCD_LVAL;
189 wire          CCD_PIXCLK;
190 wire          CCD_MCLK; //  CCD Master Clock
191 
192 wire  [15:0]  Read_DATA1;
193 wire  [15:0]  Read_DATA2;
194 wire  [15:0]  Read_DATA3; // add by oomusou for RGB16
195 wire  [15:0]  Read_DATA4; // add by oomusou for RGB16
196 wire          VGA_CTRL_CLK;
197 wire  [11:0]  mCCD_DATA;
198 wire          mCCD_DVAL;
199 wire          mCCD_DVAL_d;
200 wire  [15:0]  X_Cont;
201 wire  [15:0]  Y_Cont;
202 wire  [9:0]   X_ADDR;
203 wire  [31:0]  Frame_Cont;
204 wire          DLY_RST_0;
205 wire          DLY_RST_1;
206 wire          DLY_RST_2;
207 wire          Read;
208 reg   [11:0]  rCCD_DATA;
209 reg           rCCD_LVAL;
210 reg           rCCD_FVAL;
211 wire  [11:0]  sCCD_R;
212 wire  [11:0]  sCCD_G;
213 wire  [11:0]  sCCD_B;
214 wire          sCCD_DVAL;
215 reg   [1:0]   rClk;
216 wire          sdram_ctrl_clk;
217 
218 // Touch panel signal
219 wire  [7:0] ltm_r;    //  LTM Red Data 8 Bits
220 wire  [7:0] ltm_g;    //  LTM Green Data 8 Bits
221 wire  [7:0] ltm_b;    //  LTM Blue Data 8 Bits
222 wire        ltm_nclk; //  LTM Clcok
223 wire        ltm_hd;
224 wire        ltm_vd;
225 wire        ltm_den;
226 wire        adc_dclk;
227 wire        adc_cs;
228 wire        adc_penirq_n;
229 wire        adc_busy;
230 wire        adc_din;
231 wire        adc_dout;
232 wire        adc_ltm_sclk;
233 wire        ltm_grst;
234 
235 // LTM Config
236 wire      ltm_sclk;
237 wire      ltm_sda;
238 wire      ltm_scen;
239 wire      ltm_3wirebusy_n;
240 
241 assign  CCD_DATA[0]     = GPIO_1[11];
242 assign  CCD_DATA[1]     = GPIO_1[10];
243 assign  CCD_DATA[2]     = GPIO_1[9];
244 assign  CCD_DATA[3]     = GPIO_1[8];
245 assign  CCD_DATA[4]     = GPIO_1[7];
246 assign  CCD_DATA[5]     = GPIO_1[6];
247 assign  CCD_DATA[6]     = GPIO_1[5];
248 assign  CCD_DATA[7]     = GPIO_1[4];
249 assign  CCD_DATA[8]     = GPIO_1[3];
250 assign  CCD_DATA[9]     = GPIO_1[2];
251 assign  CCD_DATA[10]    = GPIO_1[1];
252 assign  CCD_DATA[11]    = GPIO_1[0];
253 assign  GPIO_CLKOUT_N1  = CCD_MCLK;
254 assign  CCD_FVAL        = GPIO_1[18];
255 assign  CCD_LVAL        = GPIO_1[17];
256 assign  CCD_PIXCLK      = GPIO_CLKIN_N1;
257 assign  GPIO_1[15]      = 1'b1;  // tRIGGER
258 assign  GPIO_1[14]      = DLY_RST_1;
259 
260 assign  oLEDR           = iSW;
261 assign  oLEDG           = Y_Cont;
262 
263 assign  oTD1_RESET_N    = 1'b1;
264 assign  oVGA_CLOCK      = ~VGA_CTRL_CLK;
265 
266 assign  CCD_MCLK        = rClk[0];
267 assign  oUART_TXD       = iUART_RXD;
268 
269 assign  adc_penirq_n    = GPIO_CLKIN_N0;
270 assign  adc_dout        = GPIO_0[0];
271 assign  adc_busy        = GPIO_CLKIN_P0;
272 assign  GPIO_0[1]       = adc_din;
273 assign  GPIO_0[2]       = adc_ltm_sclk;
274 assign  GPIO_0[3]       = ltm_b[3];
275 assign  GPIO_0[4]       = ltm_b[2];
276 assign  GPIO_0[5]       = ltm_b[1];
277 assign  GPIO_0[6]       = ltm_b[0];
278 assign  GPIO_0[7]       =~ltm_nclk;
279 assign  GPIO_0[8]       = ltm_den;
280 assign  GPIO_0[9]       = ltm_hd;
281 assign  GPIO_0[10]      = ltm_vd;
282 assign  GPIO_0[11]      = ltm_b[4];
283 assign  GPIO_0[12]      = ltm_b[5];
284 assign  GPIO_0[13]      = ltm_b[6];
285 assign  GPIO_CLKOUT_N0  = ltm_b[7];
286 assign  GPIO_0[14]      = ltm_g[0];
287 assign  GPIO_CLKOUT_P0  = ltm_g[1];
288 assign  GPIO_0[15]      = ltm_g[2];
289 assign  GPIO_0[16]      = ltm_g[3];
290 assign  GPIO_0[17]      = ltm_g[4];
291 assign  GPIO_0[18]      = ltm_g[5];
292 assign  GPIO_0[19]      = ltm_g[6];
293 assign  GPIO_0[20]      = ltm_g[7];
294 assign  GPIO_0[21]      = ltm_r[0];
295 assign  GPIO_0[22]      = ltm_r[1];
296 assign  GPIO_0[23]      = ltm_r[2];
297 assign  GPIO_0[24]      = ltm_r[3];
298 assign  GPIO_0[25]      = ltm_r[4];
299 assign  GPIO_0[26]      = ltm_r[5];
300 assign  GPIO_0[27]      = ltm_r[6];
301 assign  GPIO_0[28]      = ltm_r[7];
302 assign  GPIO_0[29]      = ltm_grst;
303 assign  GPIO_0[30]      = ltm_scen;
304 assign  GPIO_0[31]      = ltm_sda;
305 
306 assign ltm_grst         = iKEY[0];
307 assign adc_ltm_sclk     = ltm_sclk;
308 
309 always@(posedge iCLK_50)
310   rClk    <=  rClk  + 1;
311 
312 always@(posedge CCD_PIXCLK) begin
313   rCCD_DATA <=  CCD_DATA;
314   rCCD_LVAL <=  CCD_LVAL;
315   rCCD_FVAL <=  CCD_FVAL;
316 end
317 
318 Reset_Delay reset0  (
319   .iCLK(iCLK_50),
320   .iRST(iKEY[0]),
321   .oRST_0(DLY_RST_0),
322   .oRST_1(DLY_RST_1),
323   .oRST_2(DLY_RST_2)
324 );
325 
326 CCD_Capture capture0 (
327   .oDATA(mCCD_DATA),
328   .oDVAL(mCCD_DVAL),
329   .oX_Cont(X_Cont),
330   .oY_Cont(Y_Cont),
331   .oFrame_Cont(Frame_Cont),
332   .iDATA(rCCD_DATA),
333   .iFVAL(rCCD_FVAL),
334   .iLVAL(rCCD_LVAL),
335   .iSTART(!iKEY[3]),
336   .iEND(!iKEY[2]),
337   .iCLK(CCD_PIXCLK),
338   .iRST(DLY_RST_2)
339 );
340 
341 RAW2RGB rgb0 (
342   .iCLK(CCD_PIXCLK),
343   .iRST_n(DLY_RST_1),
344   .iData(mCCD_DATA),
345   .iDval(mCCD_DVAL),
346   .oRed(sCCD_R),
347   .oGreen(sCCD_G),
348   .oBlue(sCCD_B),
349   .oDval(sCCD_DVAL),
350   .iMIRROR(iSW[17]),
351   .iX_Cont(X_Cont),
352   .iY_Cont(Y_Cont)
353 );
354 
355 SEG7_LUT_8  seg0 (
356   .oSEG0(oHEX0_D),
357   .oSEG1(oHEX1_D),
358   .oSEG2(oHEX2_D),
359   .oSEG3(oHEX3_D),
360   .oSEG4(oHEX4_D),
361   .oSEG5(oHEX5_D),
362   .oSEG6(oHEX6_D),
363   .oSEG7(oHEX7_D),
364   .iDIG(Frame_Cont[31:0])
365 );
366 
367 vga_pll vga_pll0 (
368   .inclk0(iCLK_50_2),
369   .c0(ltm_nclk)
370 );
371 
372 sdram_pll sdram_pll0 (
373   .inclk0(iCLK_50_3),
374   .c0(sdram_ctrl_clk),
375   .c1(oDRAM0_CLK),
376   .c2(oDRAM1_CLK)
377 );
378 
379 Sdram_Control_4Port sdram0 (
380   //  HOST Side
381   .REF_CLK(iCLK_50),
382   .RESET_N(1'b1),
383   .CLK(sdram_ctrl_clk),
384   //  FIFO Write Side 1
385   .WR1_DATA({sCCD_R[11:7], sCCD_G[11:6],  sCCD_B[11:7]}),
386   .WR1(sCCD_DVAL),
387   .WR1_ADDR(0),
388   .WR1_MAX_ADDR(800*480),
389   .WR1_LENGTH(9'h100),
390   .WR1_LOAD(!DLY_RST_0),
391   .WR1_CLK(CCD_PIXCLK),
392   //  FIFO Write Side 1
393   .WR2_DATA({sCCD_R[11:7], sCCD_G[11:6],  sCCD_B[11:7]}),
394   .WR2(sCCD_DVAL),
395   .WR2_ADDR(22'h100000),
396   .WR2_MAX_ADDR(22'h100000 + 800*480),
397   .WR2_LENGTH(9'h100),
398   .WR2_LOAD(!DLY_RST_0),
399   .WR2_CLK(CCD_PIXCLK),
400   //  FIFO Read Side 1 to LTM
401   .RD1_DATA(Read_DATA3),
402   .RD1(Read),
403   .RD1_ADDR(0),
404   .RD1_MAX_ADDR(800*480),
405   .RD1_LENGTH(9'h100),
406   .RD1_LOAD(!DLY_RST_0),
407   .RD1_CLK(~ltm_nclk),
408   //  FIFO Read Side 1
409   .RD2_DATA(Read_DATA4),
410   .RD2(Read),
411   .RD2_ADDR(22'h100000 + 800*480 + 200),
412   .RD2_MAX_ADDR(22'h100000 + 800*480 + 300),
413   .RD2_LENGTH(9'h100),
414   .RD2_LOAD(!DLY_RST_0),
415   .RD2_CLK(~ltm_nclk),
416   //  SDRAM Side
417   .SA(oDRAM0_A[11:0]),
418   .BA(oDRAM0_BA),
419   .CS_N(oDRAM0_CS_N),
420   .CKE(oDRAM0_CKE),
421   .RAS_N(oDRAM0_RAS_N),
422   .CAS_N(oDRAM0_CAS_N),
423   .WE_N(oDRAM0_WE_N),
424   .DQ(DRAM_DQ[15:0]),
425   .DQM({oDRAM0_UDQM1,oDRAM0_LDQM0})
426 );
427 
428 // add by oomusou for RGB16
429 assign Read_DATA1 = {Read_DATA3[10:6], Read_DATA3[4:0], 5'h00};
430 assign Read_DATA2 = {Read_DATA3[5:5], 4'h0, Read_DATA3[15:11], 5'h00};
431 
432 I2C_CCD_Config ccd_config0 (
433   //  Host Side
434   .iCLK(iCLK_50),
435   .iRST_N(DLY_RST_1),
436   .iEXPOSURE_ADJ(iKEY[1]),
437   .iEXPOSURE_DEC_p(iSW[0]),
438   .iMIRROR_SW(iSW[17]),
439   //  I2C Side
440   .I2C_SCLK(GPIO_1[20]),
441   .I2C_SDAT(GPIO_1[19])
442 );
443 
444 touch_tcon tcon0 (
445   .iCLK(ltm_nclk),
446   .iRST_n(DLY_RST_2),
447   // sdram side
448   .iREAD_DATA1(Read_DATA1),
449   .iREAD_DATA2(Read_DATA2),
450   .oREAD_SDRAM_EN(Read),
451   // lcd side
452   .oLCD_R(ltm_r),
453   .oLCD_G(ltm_g),
454   .oLCD_B(ltm_b),
455   .oHD(ltm_hd),
456   .oVD(ltm_vd),
457   .oDEN(ltm_den)
458 );
459 
460 lcd_3wire_config wire0 (
461   // Host Side
462   .iCLK(iCLK_50),
463   .iRST_n(DLY_RST_0),
464   // 3 wire Side
465   .o3WIRE_SCLK(ltm_sclk),
466   .io3WIRE_SDAT(ltm_sda),
467   .o3WIRE_SCEN(ltm_scen),
468   .o3WIRE_BUSY_n(ltm_3wirebusy_n)
469 );
470 
471 endmodule


379行

Sdram_Control_4Port sdram0 (
 
//  HOST Side
  .REF_CLK(iCLK_50),
  .RESET_N(
1'b1),
  .CLK(sdram_ctrl_clk),
 
//  FIFO Write Side 1
  .WR1_DATA({sCCD_R[11:7], sCCD_G[11:6],  sCCD_B[11:7]}),
  .WR1(sCCD_DVAL),
  .WR1_ADDR(
0),
  .WR1_MAX_ADDR(
800*480),
  .WR1_LENGTH(
9'h100),
  .WR1_LOAD(!DLY_RST_0),
  .WR1_CLK(CCD_PIXCLK),
 
//  FIFO Write Side 1
  .WR2_DATA({sCCD_R[11:7], sCCD_G[11:6],  sCCD_B[11:7]}),
  .WR2(sCCD_DVAL),
  .WR2_ADDR(
22'h100000),
  .WR2_MAX_ADDR(22'h100000 + 800*480),
  .WR2_LENGTH(9'h100),
  .WR2_LOAD(!DLY_RST_0),
  .WR2_CLK(CCD_PIXCLK),
 
//  FIFO Read Side 1 to LTM
  .RD1_DATA(Read_DATA3),
  .RD1(Read),
  .RD1_ADDR(
0),
  .RD1_MAX_ADDR(
800*480),
  .RD1_LENGTH(
9'h100),
  .RD1_LOAD(!DLY_RST_0),
  .RD1_CLK(
~ltm_nclk),
 
//  FIFO Read Side 1
  .RD2_DATA(Read_DATA4),
  .RD2(Read),
  .RD2_ADDR(
22'h100000 + 800*480 + 200),
  .RD2_MAX_ADDR(22'h100000 + 800*480 + 300),
  .RD2_LENGTH(9'h100),
  .RD2_LOAD(!DLY_RST_0),
  .RD2_CLK(
~ltm_nclk),
 
//  SDRAM Side
  .SA(oDRAM0_A[11:0]),
  .BA(oDRAM0_BA),
  .CS_N(oDRAM0_CS_N),
  .CKE(oDRAM0_CKE),
  .RAS_N(oDRAM0_RAS_N),
  .CAS_N(oDRAM0_CAS_N),
  .WE_N(oDRAM0_WE_N),
  .DQ(DRAM_DQ[
15:0]),
  .DQM({oDRAM0_UDQM1,oDRAM0_LDQM0})
);


原來在DE2_70_D5M_LTM中,是使用2顆SDRAM來做frame buffer,為了模擬DE2的1顆SDRAM,所以我只用了一個Sdram_Control_4Port。

384行

//  FIFO Write Side 1
.WR1_DATA({sCCD_R[11:7], sCCD_G[11:6],  sCCD_B[11:7]}),
.WR1(sCCD_DVAL),
.WR1_ADDR(
0),
.WR1_MAX_ADDR(
800*480),
.WR1_LENGTH(
9'h100),
.WR1_LOAD(!DLY_RST_0),
.WR1_CLK(CCD_PIXCLK),
 


.WR1_DATA為16 bit,使用RGB16(R5G6B5)的方式傳入,不一定得跟我一樣使用R5G6B5的方式,若你要R5G5G5也可以,反正最多只能16 bit就好。

sCCD_R原來為12 bit,我只取高5 bit而以。

392行

//  FIFO Write Side 1
.WR2_DATA({sCCD_R[11:7], sCCD_G[11:6],  sCCD_B[11:7]}),
.WR2(sCCD_DVAL),
.WR2_ADDR(
22'h100000),
.WR2_MAX_ADDR(22'h100000 + 800*480),
.WR2_LENGTH(9'h100),
.WR2_LOAD(!DLY_RST_0),
.WR2_CLK(CCD_PIXCLK),
 


FIFO Write Side 2就可以自由應用了,這裡之所以也傳入RGB16,是因為網友想將capture的影像放在SDRAM的其他位置做處理,所以在此範例又傳入RGB16,只是address有所不同,實際可依你的需要善用FIFO Write Side 2。

400行

//  FIFO Read Side 1 to LTM
.RD1_DATA(Read_DATA3),
.RD1(Read),
.RD1_ADDR(
0),
.RD1_MAX_ADDR(
800*480),
.RD1_LENGTH(
9'h100),
.RD1_LOAD(!DLY_RST_0),
.RD1_CLK(
~ltm_nclk),
 


FIFO Read Side1負責將資料傳給LTM controller,注意我另外用了wire Read_DATA3,而不是原來的Read_DATA1,理由我稍後會做解釋。

408行

//  FIFO Read Side 1
.RD2_DATA(Read_DATA4),
.RD2(Read),
.RD2_ADDR(
22'h100000 + 800*480 + 200),
.RD2_MAX_ADDR(22'h100000 + 800*480 + 300),
.RD2_LENGTH(9'h100),
.RD2_LOAD(!DLY_RST_0),
.RD2_CLK(
~ltm_nclk),


FIFO Read Side 1也可以自由應用,因為網友想要解取部分影像,所以才這樣寫,實際可依你的需要善用FIFO Read Side 2。

444行

touch_tcon tcon0 (
  .iCLK(ltm_nclk),
  .iRST_n(DLY_RST_2),
 
// sdram side
  .iREAD_DATA1(Read_DATA1),
  .iREAD_DATA2(Read_DATA2),
  .oREAD_SDRAM_EN(Read),
 
// lcd side
  .oLCD_R(ltm_r),
  .oLCD_G(ltm_g),
  .oLCD_B(ltm_b),
  .oHD(ltm_hd),
  .oVD(ltm_vd),
  .oDEN(ltm_den)
);


這是LTM controller,需要傳入Read_DATA1與Read_DATA2,不過因為我們已經改用RGB16,在不更改touch_tcon module的前提下,我們需要對Read_DATA1與Read_DATA2做手腳。

428行

// add by oomusou for RGB16
assign Read_DATA1 = {Read_DATA3[10:6], Read_DATA3[4:0], 5'h00};
assign Read_DATA2 = {Read_DATA3[5:5], 4'h0, Read_DATA3[15:11], 5'h00};


本文最關鍵的地方在這裡,原來的Read_DATA1是由{sCCD_G[11:7],  sCCD_B[11:2]}所構成,而Read_DATA2是由{sCCD_G[6:2], sCCD_R[11:2]}所構成,但現在由Sdram_Control_4Port的RD1_DATA吐出來的是Read_DATA3,是由{sCCD_R[11:7], sCCD_G[11:6],  sCCD_B[11:7]}所構成,所以必須將Read_DATA3轉換成Read_DATA1與Read_DATA2原本的格式,LTM才會顯示正常,否則會有色偏的情形

由於RGB16取的是高5 bit,所以R/G/B的低5 bit必須補0,如此RGB皆以10 bit傳進LTM controller。

完整程式下載
DE2_70_D5M_LTM_RGB32.7z
DE2_70_D5M_LTM_RGB16.7z

Conclusion
藉由RGB16的方式,可以省下一半的SDRAM另做他用,而且畫質仍可接受,這種技巧在DE2這種只有1顆SDRAM的環境下非常有用。

See Also
(原創) 如何計算SDRAM使用頻寬? (SOC) (DE2) (DE2-70) (TRDB-DC2) (TRDB-D5M) (TRDB-LCM) (TRDB-LTM)

posted on 2008-10-24 17:40  真 OO无双  阅读(10442)  评论(44编辑  收藏  举报

导航