(原創) 如何控制DE2 VGA輸出時某座標的顏色? (IC Design) (DE2) (Quartus II)
Abstract
在友晶科技的DE2_CCD範例中,將CMOS的影像直接在VGA輸出,是否能控制VGA的座標,並顯示不同的影像呢?
Introduction
版權聲明:本文根據友晶科技光碟所附的範例程式加以修改,原範例版權歸友晶科技所有。
使用環境:Quartus II 7.2 SP1 + DE2(Cyclone II EP2C35F627C6) + TRDB_DC2
本程式依照友晶科技的DE2_CCD範例加以修改。
VGA影像輸出的好壞,除了決定於VGA螢幕外,VGA Controller也扮演很重要的角色,我們可以在VGA Controller埋入影像處理的演算法改善畫值,但首先要面對的,就是取得輸出時VGA的X與Y作標,這樣才能做後續的影像處理。
VGA_Controller.v
1 module VGA_Controller (
2 // Host Side
3 iRed,
4 iGreen,
5 iBlue,
6 oRequest,
7 // VGA Side
8 oVGA_R,
9 oVGA_G,
10 oVGA_B,
11 oVGA_H_SYNC,
12 oVGA_V_SYNC,
13 oVGA_SYNC,
14 oVGA_BLANK,
15 oVGA_CLOCK,
16 // Control Signal
17 iCLK,
18 iRST_N
19 );
20
21 `include "VGA_Param.h"
22
23 // Host Side
24 input [9:0] iRed;
25 input [9:0] iGreen;
26 input [9:0] iBlue;
27 output reg oRequest;
28
29 // VGA Side
30 output reg [9:0] oVGA_R;
31 output reg [9:0] oVGA_G;
32 output reg [9:0] oVGA_B;
33 output reg oVGA_H_SYNC;
34 output reg oVGA_V_SYNC;
35 output oVGA_SYNC;
36 output oVGA_BLANK;
37 output oVGA_CLOCK;
38 // Control Signal
39 input iCLK;
40 input iRST_N;
41
42 // Internal Registers and Wires
43 reg [9:0] H_Cont;
44 reg [9:0] V_Cont;
45 reg [9:0] Cur_Color_R;
46 reg [9:0] Cur_Color_G;
47 reg [9:0] Cur_Color_B;
48 wire mCursor_EN;
49 wire mRed_EN;
50 wire mGreen_EN;
51 wire mBlue_EN;
52
53 // add by oomusou
54 reg [9:0] coord_x;
55 reg [9:0] coord_y;
56
57 assign oVGA_BLANK = oVGA_H_SYNC & oVGA_V_SYNC;
58 assign oVGA_SYNC = 1'b0;
59 assign oVGA_CLOCK = iCLK;
60
61 // add by oomusou
62 always@(H_Cont or V_Cont) begin
63 if (H_Cont >= X_START && H_Cont < X_START + H_SYNC_ACT &&
64 V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT)
65 oVGA_R = iRed;
66 else
67 oVGA_R = 0;
68
69 if (H_Cont >= X_START && H_Cont < X_START + H_SYNC_ACT &&
70 V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT)
71 oVGA_G = iGreen;
72 else
73 oVGA_G = 0;
74
75 if (H_Cont >= X_START && H_Cont < X_START + H_SYNC_ACT &&
76 V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT)
77 oVGA_B = iBlue;
78 else
79 oVGA_B = 0;
80
81 if (coord_x > 200 && coord_x < 320 &&
82 coord_y > 200 && coord_y < 240) begin
83 oVGA_R = 10'h000;
84 oVGA_G = 10'h000;
85 oVGA_B = 10'h000;
86 end
87 end
88
89 // Pixel LUT Address Generator
90 always@(posedge iCLK or negedge iRST_N) begin
91 if (!iRST_N) begin
92 oRequest <= 0;
93 coord_x <= 0;
94 coord_y <= 0;
95 end
96 else begin
97 if (H_Cont >= X_START - 2 && H_Cont < X_START + H_SYNC_ACT-2 &&
98 V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT) begin
99 oRequest <= 1;
100 coord_x <= H_Cont - (X_START - 2);
101 coord_y <= V_Cont - Y_START;
102 end
103 else
104 oRequest <= 0;
105 end
106 end
107
108 // H_Sync Generator, Ref. 25.175 MHz Clock
109 always@(posedge iCLK or negedge iRST_N) begin
110 if (!iRST_N) begin
111 H_Cont <= 0;
112 oVGA_H_SYNC <= 0;
113 end
114 else begin
115 // H_Sync Counter
116 if (H_Cont < H_SYNC_TOTAL)
117 H_Cont <= H_Cont + 1;
118 else
119 H_Cont <= 0;
120
121 // H_Sync Generator
122 if (H_Cont < H_SYNC_CYC)
123 oVGA_H_SYNC <= 0;
124 else
125 oVGA_H_SYNC <= 1;
126 end
127 end
128
129 // V_Sync Generator, Ref. H_Sync
130 always@(posedge iCLK or negedge iRST_N) begin
131 if (!iRST_N) begin
132 V_Cont <= 0;
133 oVGA_V_SYNC <= 0;
134 end
135 else begin
136 // When H_Sync Re-start
137 if (H_Cont == 0) begin
138 // V_Sync Counter
139 if (V_Cont < V_SYNC_TOTAL)
140 V_Cont <= V_Cont + 1;
141 else
142 V_Cont <= 0;
143
144 // V_Sync Generator
145 if (V_Cont < V_SYNC_CYC)
146 oVGA_V_SYNC <= 0;
147 else
148 oVGA_V_SYNC <= 1;
149 end
150 end
151 end
152
153 endmodule
2 // Host Side
3 iRed,
4 iGreen,
5 iBlue,
6 oRequest,
7 // VGA Side
8 oVGA_R,
9 oVGA_G,
10 oVGA_B,
11 oVGA_H_SYNC,
12 oVGA_V_SYNC,
13 oVGA_SYNC,
14 oVGA_BLANK,
15 oVGA_CLOCK,
16 // Control Signal
17 iCLK,
18 iRST_N
19 );
20
21 `include "VGA_Param.h"
22
23 // Host Side
24 input [9:0] iRed;
25 input [9:0] iGreen;
26 input [9:0] iBlue;
27 output reg oRequest;
28
29 // VGA Side
30 output reg [9:0] oVGA_R;
31 output reg [9:0] oVGA_G;
32 output reg [9:0] oVGA_B;
33 output reg oVGA_H_SYNC;
34 output reg oVGA_V_SYNC;
35 output oVGA_SYNC;
36 output oVGA_BLANK;
37 output oVGA_CLOCK;
38 // Control Signal
39 input iCLK;
40 input iRST_N;
41
42 // Internal Registers and Wires
43 reg [9:0] H_Cont;
44 reg [9:0] V_Cont;
45 reg [9:0] Cur_Color_R;
46 reg [9:0] Cur_Color_G;
47 reg [9:0] Cur_Color_B;
48 wire mCursor_EN;
49 wire mRed_EN;
50 wire mGreen_EN;
51 wire mBlue_EN;
52
53 // add by oomusou
54 reg [9:0] coord_x;
55 reg [9:0] coord_y;
56
57 assign oVGA_BLANK = oVGA_H_SYNC & oVGA_V_SYNC;
58 assign oVGA_SYNC = 1'b0;
59 assign oVGA_CLOCK = iCLK;
60
61 // add by oomusou
62 always@(H_Cont or V_Cont) begin
63 if (H_Cont >= X_START && H_Cont < X_START + H_SYNC_ACT &&
64 V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT)
65 oVGA_R = iRed;
66 else
67 oVGA_R = 0;
68
69 if (H_Cont >= X_START && H_Cont < X_START + H_SYNC_ACT &&
70 V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT)
71 oVGA_G = iGreen;
72 else
73 oVGA_G = 0;
74
75 if (H_Cont >= X_START && H_Cont < X_START + H_SYNC_ACT &&
76 V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT)
77 oVGA_B = iBlue;
78 else
79 oVGA_B = 0;
80
81 if (coord_x > 200 && coord_x < 320 &&
82 coord_y > 200 && coord_y < 240) begin
83 oVGA_R = 10'h000;
84 oVGA_G = 10'h000;
85 oVGA_B = 10'h000;
86 end
87 end
88
89 // Pixel LUT Address Generator
90 always@(posedge iCLK or negedge iRST_N) begin
91 if (!iRST_N) begin
92 oRequest <= 0;
93 coord_x <= 0;
94 coord_y <= 0;
95 end
96 else begin
97 if (H_Cont >= X_START - 2 && H_Cont < X_START + H_SYNC_ACT-2 &&
98 V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT) begin
99 oRequest <= 1;
100 coord_x <= H_Cont - (X_START - 2);
101 coord_y <= V_Cont - Y_START;
102 end
103 else
104 oRequest <= 0;
105 end
106 end
107
108 // H_Sync Generator, Ref. 25.175 MHz Clock
109 always@(posedge iCLK or negedge iRST_N) begin
110 if (!iRST_N) begin
111 H_Cont <= 0;
112 oVGA_H_SYNC <= 0;
113 end
114 else begin
115 // H_Sync Counter
116 if (H_Cont < H_SYNC_TOTAL)
117 H_Cont <= H_Cont + 1;
118 else
119 H_Cont <= 0;
120
121 // H_Sync Generator
122 if (H_Cont < H_SYNC_CYC)
123 oVGA_H_SYNC <= 0;
124 else
125 oVGA_H_SYNC <= 1;
126 end
127 end
128
129 // V_Sync Generator, Ref. H_Sync
130 always@(posedge iCLK or negedge iRST_N) begin
131 if (!iRST_N) begin
132 V_Cont <= 0;
133 oVGA_V_SYNC <= 0;
134 end
135 else begin
136 // When H_Sync Re-start
137 if (H_Cont == 0) begin
138 // V_Sync Counter
139 if (V_Cont < V_SYNC_TOTAL)
140 V_Cont <= V_Cont + 1;
141 else
142 V_Cont <= 0;
143
144 // V_Sync Generator
145 if (V_Cont < V_SYNC_CYC)
146 oVGA_V_SYNC <= 0;
147 else
148 oVGA_V_SYNC <= 1;
149 end
150 end
151 end
152
153 endmodule
89行
// Pixel LUT Address Generator
always@(posedge iCLK or negedge iRST_N) begin
if (!iRST_N) begin
oRequest <= 0;
coord_x <= 0;
coord_y <= 0;
end
else begin
if (H_Cont >= X_START - 2 && H_Cont < X_START + H_SYNC_ACT-2 &&
V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT) begin
oRequest <= 1;
coord_x <= H_Cont - (X_START - 2);
coord_y <= V_Cont - Y_START;
end
else
oRequest <= 0;
end
end
always@(posedge iCLK or negedge iRST_N) begin
if (!iRST_N) begin
oRequest <= 0;
coord_x <= 0;
coord_y <= 0;
end
else begin
if (H_Cont >= X_START - 2 && H_Cont < X_START + H_SYNC_ACT-2 &&
V_Cont >= Y_START && V_Cont < Y_START + V_SYNC_ACT) begin
oRequest <= 1;
coord_x <= H_Cont - (X_START - 2);
coord_y <= V_Cont - Y_START;
end
else
oRequest <= 0;
end
end
加入coord_x與coord_y兩reg,計算出目前的X與Y座標。
81行
if (coord_x > 200 && coord_x < 320 &&
coord_y > 200 && coord_y < 240) begin
oVGA_R = 10'h000;
oVGA_G = 10'h000;
oVGA_B = 10'h000;
end
coord_y > 200 && coord_y < 240) begin
oVGA_R = 10'h000;
oVGA_G = 10'h000;
oVGA_B = 10'h000;
end
如此就能在指定的座標下指定特定的顏色,以上會在中間的區域顯示黑色,如下圖所示。
完整程式碼下載
友晶科技範例 DE2_CCD.7z
本文程式 DE2_CCD_CV.7z
Conclusion
抓出X與Y座標只是初步,若要能做影響處理,可能需要搭配一個FIFO,將目前frame的所有pixel的資訊流住,目前我正在朝這方向努力當中。
See Also
(原創) 如何將CMOS彩色影像轉換成灰階影像? (SOC) (DE2)
(原創) 如何控制TRDB-LTM輸出時某座標的顏色? (SOC) (DE2-70) (TRDB-LTM)