VGA an 50MHZ anpassen, wie geht das?

Gast #4975288
Lesenswert?

Wie kann man diese VGA-CLK bitte für ein Board mit 50MHZ anpassen?

Danke.
1
`default_nettype none      //disable implicit definitions by Verilog
2

3
module top(        //top module and signals wired to FPGA pins
4
  CLK100MHz,
5
  vga_r,
6
  vga_g,
7
  vga_b,
8
  vga_hs,
9
  vga_vs,
10
  ps2_clk,
11
  ps2_data
12
);
13

14
input      CLK100MHz;  // Oscillator input 100Mhz
15
output  [2:0]     vga_r;    // VGA Red 3 bit
16
output  [2:0]     vga_g;    // VGA Green 3 bit
17
output  [2:0]     vga_b;    // VGA Blue 3 bit
18
output            vga_hs;    // H-sync pulse 
19
output            vga_vs;    // V-sync pulse
20
input      ps2_clk;  // PS2 clock
21
input      ps2_data;  // PS2 data
22

23

24
parameter h_pulse   = 96;  //H-SYNC pulse width 96 * 40 ns (25 Mhz) = 3.84 uS
25
parameter h_bp      = 48;  //H-BP back porch pulse width
26
parameter h_pixels  = 640;  //H-PIX Number of pixels horisontally
27
parameter h_fp      = 16;  //H-FP front porch pulse width
28
parameter h_pol     = 1'b0;  //H-SYNC polarity
29
parameter h_frame   = 800;  //800 = 96 (H-SYNC) + 48 (H-BP) + 640 (H-PIX) + 16 (H-FP)
30
parameter v_pulse   = 2;  //V-SYNC pulse width
31
parameter v_bp      = 33;  //V-BP back porch pulse width
32
parameter v_pixels  = 480;  //V-PIX Number of pixels vertically
33
parameter v_fp      = 10;  //V-FP front porch pulse width
34
parameter v_pol     = 1'b1;  //V-SYNC polarity
35
parameter v_frame   = 525;  // 525 = 2 (V-SYNC) + 33 (V-BP) + 480 (V-PIX) + 10 (V-FP)
36

37
parameter square_size = 10;  //size of the square we will move
38
parameter init_x = 320;    //initial square position X
39
parameter init_y = 240;    //initial square position Y
40

41
reg  [1:0]    clk_div;  // 2 bit counter
42
wire      vga_clk;  
43

44
assign   vga_clk   = clk_div[1];    // 25Mhz clock = 100Mhz divided by 2-bit counter
45

46
always @ (posedge CLK100MHz) begin    // 2-bt counter ++ on each positive edge of 100Mhz clock
47
  clk_div <= clk_div + 2'b1;
48
end
49

50
reg     [2:0]     vga_r_r;  //VGA color registers R,G,B x 3 bit
51
reg     [2:0]     vga_g_r;
52
reg     [2:0]     vga_b_r;
53
reg               vga_hs_r;  //H-SYNC register
54
reg               vga_vs_r;  //V-SYNC register
55

56
assign   vga_r     = vga_r_r;    //assign the output signals for VGA to the VGA registers
57
assign   vga_g     = vga_g_r;
58
assign   vga_b     = vga_b_r;
59
assign   vga_hs     = vga_hs_r;
60
assign   vga_vs     = vga_vs_r;
61

62
reg     [7:0]    timer_t = 8'b0;  // 8 bit timer with 0 initialization
63
reg               reset = 1;  
64
reg     [9:0]     c_row;    //complete frame register row
65
reg     [9:0]     c_col;    //complete frame register colum
66
reg     [9:0]     c_hor;    //visible frame register horisontally
67
reg     [9:0]     c_ver;    //visible  frame register vertically
68

69
reg      disp_en;  //display enable flag
70

71
reg  [9:0]    sq_pos_x;  //position of square center X, Y
72
reg  [9:0]    sq_pos_y;
73

74
wire  [9:0]    l_sq_pos_x;  //upper left and down right corners of the square
75
wire  [9:0]    r_sq_pos_x;
76
wire  [9:0]    u_sq_pos_y;
77
wire  [9:0]    d_sq_pos_y;
78

79
assign   l_sq_pos_x   = sq_pos_x - square_size;
80
assign   r_sq_pos_x   = sq_pos_x + square_size;
81
assign   u_sq_pos_y   = sq_pos_y - square_size;
82
assign   d_sq_pos_y   = sq_pos_y + square_size;
83

84
reg  [3:0]    ps2_cntr;    // 4-bit PS2 clock counter
85
reg  [7:0]    ps2_data_reg;    // 8-bit PS2 data register
86
reg  [7:0]    ps2_data_reg_prev;  // previous 8-bit PS data register
87
reg  [7:0]    ps2_data_reg_prev1;  // previous previous 8-bit data register
88
reg  [10:0]    ps2_dat_r;    // 11-bit complete PS2 frame register
89

90
reg  [1:0]    ps2_clk_buf;    // PS2 clock buffer
91
wire      ps2_clk_pos;    // PS2 positive edge detected signal
92

93
reg      u_arr = 0;    //PS2 arrow keys detect flags
94
reg      l_arr = 0;
95
reg      d_arr = 0;
96
reg      r_arr = 0;
97

98
reg  [20:0]  arr_timer;  // delay between key service
99

100
reg  [19:0]  sq_figure  [0:19];
101

102
wire  [4:0]  sq_fig_x;
103
wire  [4:0]  sq_fig_y;
104

105
assign sq_fig_x = c_col - l_sq_pos_x;      // our figure's x axis when in square boundary
106
assign sq_fig_y = c_row - u_sq_pos_y;      // our figure's y axis when in square boundary
107

108
assign ps2_clk_pos = (ps2_clk_buf == 2'b01);  // edge detector positive edge is when the buffer is '10'
109

110
always @ (posedge vga_clk) begin        //25Mhz clock
111

112
  if(timer_t > 250) begin          // generate 10 uS RESET signal 
113
    reset <= 0;
114
  end
115
  else begin
116
    reset <= 1;          //while in reset display is disabled, suare is set to initial position
117
    timer_t <= timer_t + 1;
118
    disp_en <= 0;      
119
    sq_pos_x <= init_x;        
120
    sq_pos_y <= init_y;
121
  end
122
  
123
  if(reset == 1) begin          //while RESET is high init counters
124
  
125
  
126
    sq_figure[0][19:0] <=  20'b00000000000000000000;
127
    sq_figure[1][19:0] <=  20'b00000001111100000000;
128
    sq_figure[2][19:0] <=  20'b00000111111111000000;
129
    sq_figure[3][19:0] <=  20'b00011111111111110000;
130
    sq_figure[4][19:0] <=  20'b00111111111111111000;
131
    sq_figure[5][19:0] <=  20'b00111111111111111000;
132
    sq_figure[6][19:0] <=  20'b01111111111111111100;
133
    sq_figure[7][19:0] <=  20'b01111111111111111100;
134
    sq_figure[8][19:0] <=  20'b11111111111111111110;
135
    sq_figure[9][19:0] <=  20'b11111111111111111110;
136
    sq_figure[10][19:0] <=  20'b11111111111111111110;
137
    sq_figure[11][19:0] <=  20'b11111111111111111110;
138
    sq_figure[12][19:0] <=  20'b11111111111111111110;
139
    sq_figure[13][19:0] <=  20'b01111111111111111100;
140
    sq_figure[14][19:0] <=  20'b01111111111111111100;
141
    sq_figure[15][19:0] <=  20'b00111111111111111000;
142
    sq_figure[16][19:0] <=  20'b00111111111111111000;
143
    sq_figure[17][19:0] <=  20'b00011111111111110000;
144
    sq_figure[18][19:0] <=  20'b00000111111111000000;
145
    sq_figure[19][19:0] <=  20'b00000001111100000000;
146
  
147
    c_hor <= 0;
148
    c_ver <= 0;
149
    vga_hs_r <= 1;
150
    vga_vs_r <= 0;
151
    c_row <= 0;
152
    c_col <= 0;
153
  end
154
  else begin            // update current beam position
155
    if(c_hor < h_frame - 1) begin
156
      c_hor <= c_hor + 1;
157
    end
158
    else begin
159
      c_hor <= 0;
160
      if(c_ver < v_frame - 1) begin
161
        c_ver <= c_ver + 1;
162
      end
163
      else begin
164
        c_ver <= 0;
165
      end
166
    end
167
  end
168
  if(c_hor < h_pixels + h_fp + 1 || c_hor > h_pixels + h_fp + h_pulse) begin  // H-SYNC generator
169
    vga_hs_r <= ~h_pol;
170
  end
171
  else begin
172
    vga_hs_r <= h_pol;
173
  end
174
  if(c_ver < v_pixels + v_fp || c_ver > v_pixels + v_fp + v_pulse) begin    //V-SYNC generator
175
    vga_vs_r <= ~v_pol;
176
  end
177
  else begin
178
    vga_vs_r <= v_pol;
179
  end
180
  if(c_hor < h_pixels) begin    //c_col and c_row counters are updated only in the visible time-frame
181
    c_col <= c_hor;
182
  end
183
  if(c_ver < v_pixels) begin
184
    c_row <= c_ver;
185
  end
186
  if(c_hor < h_pixels && c_ver < v_pixels) begin    //VGA color signals are enabled only in the visible time frame
187
    disp_en <= 1;
188
  end
189
  else begin
190
    disp_en <= 0;
191
  end
192
  if(disp_en == 1 && reset == 0) begin
193
    if(c_row == 0 || c_col == 0 || c_row == v_pixels-1 || c_col == h_pixels-1) begin  //generate red frame with size 640x480
194
      vga_r_r <= 7;
195
      vga_g_r <= 0;
196
      vga_b_r <= 0;
197
    end
198
    else if(c_col > l_sq_pos_x && c_col < r_sq_pos_x && c_row > u_sq_pos_y && c_row < d_sq_pos_y) begin  //generate blue square
199
      //vga_r_r <= 7;
200
      //vga_g_r <= 0;
201
      //vga_b_r <= 7;
202
      if(sq_figure[sq_fig_y][sq_fig_x] == 1) begin
203
      vga_r_r <= 7;
204
      vga_g_r <= 0;
205
      vga_b_r <= 7;
206
      end
207
      else begin
208
      vga_r_r <= 0;
209
      vga_g_r <= 0;
210
      vga_b_r <= 0;
211
      end
212
    end
213
    else begin      //everything else is black
214
      vga_r_r <= 0;
215
      vga_g_r <= 0;
216
      vga_b_r <= 0;
217
    end
218
  end
219
  else begin      //when display is not enabled everything is black
220
    vga_r_r <= 0;
221
    vga_g_r <= 0;
222
    vga_b_r <= 0;
223
  end
224
  
225
  if(c_row == 1 && c_col == 1) begin    //once per video frame
226
    if(u_arr) begin
227
      if (sq_pos_y > square_size) begin
228
        sq_pos_y <= sq_pos_y - 1;
229
      end
230
      else begin
231
        u_arr <= 0;
232
        d_arr <= 1;
233
      end
234
    end;
235

236
    if(d_arr) begin
237
      if (sq_pos_y < (v_pixels - 1 - square_size)) begin
238
        sq_pos_y <= sq_pos_y + 1;
239
      end
240
      else begin
241
        d_arr <= 0;
242
        u_arr <= 1;
243
      end
244
    end;
245

246
    if(l_arr) begin
247
      if (sq_pos_x > square_size) begin
248
        sq_pos_x <= sq_pos_x - 1;
249
      end
250
      else begin
251
        l_arr <= 0;
252
        r_arr <= 1;
253
      end
254
    end;
255

256
    if(r_arr) begin
257
      if (sq_pos_x < (h_pixels - 1 - square_size)) begin
258
        sq_pos_x <= sq_pos_x + 1;
259
      end
260
      else begin
261
        r_arr <= 0;
262
        l_arr <= 1;
263
      end
264
    end;
265

266
  end
267

268
  ps2_clk_buf[1:0] <= {ps2_clk_buf[0], ps2_clk};  // shift old value left and get current value of ps2_clk
269
  if(ps2_clk_pos == 1) begin      // on positive edge
270
    ps2_cntr <= ps2_cntr + 1;
271
    if(ps2_cntr == 10) begin    // when we got 10 clocks save the PS2 data to ps2_data_reg, ps2_data_reg_prev and ps2_data_reg_prev1 
272
      ps2_cntr <= 0;      // so we have last 3 data values captured from PS2 keyboard
273
      ps2_data_reg[7] <= ps2_dat_r[0];
274
      ps2_data_reg[6] <= ps2_dat_r[1];
275
      ps2_data_reg[5] <= ps2_dat_r[2];
276
      ps2_data_reg[4] <= ps2_dat_r[3];
277
      ps2_data_reg[3] <= ps2_dat_r[4];
278
      ps2_data_reg[2] <= ps2_dat_r[5];
279
      ps2_data_reg[1] <= ps2_dat_r[6];
280
      ps2_data_reg[0] <= ps2_dat_r[7];
281
      ps2_data_reg_prev <= ps2_data_reg;
282
      ps2_data_reg_prev1 <= ps2_data_reg_prev;
283
    end
284
    ps2_dat_r <= {ps2_dat_r[9:0], ps2_data};  // data shift left
285
  end
286

287
/*  if(ps2_data_reg_prev1 == 8'he0 && ps2_data_reg_prev == 8'hf0) begin  // 0xE0 0xF0 sequaence means key released
288
    if(ps2_data_reg == 8'h75) begin
289
      u_arr <= 0;        //0x75 up key
290
    end
291
    else if(ps2_data_reg == 8'h6b) begin
292
      l_arr <= 0;        //0x6B left key
293
    end
294
    else if(ps2_data_reg == 8'h72) begin
295
      d_arr <= 0;        //0x72 down key
296
    end
297
    else if(ps2_data_reg == 8'h74) begin
298
      r_arr <= 0;        //0x74 right key
299
    end
300
  end
301
*/  
302
  arr_timer <= arr_timer + 1;
303
  
304
  if(arr_timer == 0) begin
305

306
    sq_figure[8][19:0] <=  sq_figure[8][19:0] ^ 20'b00000001111000000000;
307
    sq_figure[9][19:0] <=  sq_figure[9][19:0] ^ 20'b00000001111000000000;
308
    sq_figure[10][19:0] <=  sq_figure[10][19:0] ^ 20'b00000001111000000000;
309
    sq_figure[11][19:0] <=  sq_figure[11][19:0] ^ 20'b00000001111000000000;
310

311

312
    if(ps2_data_reg_prev == 8'he0) begin      //0xE0  means key pressed
313
      if(ps2_data_reg == 8'h75) begin    
314
        if(u_arr == 1) begin
315
          u_arr <= 1;        //0x75 up key  
316
          d_arr <= 0;
317
          l_arr <= 0;
318
          r_arr <= 0;
319
        end
320
        else begin
321
          u_arr <= 1;        //0x75 up key  
322
          d_arr <= 0;
323
        end
324
        ps2_data_reg <= 0;
325
      end
326
      if(ps2_data_reg == 8'h6b) begin    
327
        if(l_arr == 1) begin
328
          l_arr <= 1;        //0x6B left key
329
          r_arr <= 0;
330
          u_arr <= 0;
331
          d_arr <= 0;
332
        end
333
        else begin
334
          l_arr <= 1;        //0x6B left key
335
          r_arr <= 0;
336
        end
337
        ps2_data_reg <= 0;
338
      end
339
      if(ps2_data_reg == 8'h72) begin
340
        if(d_arr == 1) begin
341
          d_arr <= 1;        //0x72 down key
342
          u_arr <= 0;
343
          l_arr <= 0;
344
          r_arr <= 0;
345
        end
346
        else begin
347
          d_arr <= 1;        //0x72 down key
348
          u_arr <= 0;
349
        end
350
        ps2_data_reg <= 0;
351
      end
352
      if(ps2_data_reg == 8'h74) begin
353
        if(r_arr == 1) begin
354
          r_arr <= 1;        //0x74 right key
355
          l_arr <= 0;
356
          u_arr <= 0;
357
          d_arr <= 0;
358
        end
359
        else begin
360
          r_arr <= 1;        //0x74 right key
361
          l_arr <= 0;
362
        end
363
        ps2_data_reg <= 0;
364
      end
365
    end  
366
  end
367

368

369
end
370

371
endmodule
Moderator (Firma: Titel) Persönliche Seite #4975306
Lesenswert?

bernd schrieb:
> Wie kann man diese VGA-CLK bitte für ein Board mit 50MHZ anpassen?
Nimm eine PLL/DLL/DCM und mach aus den 50Mhz die 100MHz, die das Design 
wil...


> Wie kann man diese VGA-CLK bitte für ein Board mit 50MHZ anpassen?
Wo ist der "Taktteiler"?
1
assign   vga_clk   = clk_div[1];    // 25Mhz clock = 100Mhz divided by 2-bit counter
2

3
always @ (posedge CLK100MHz) begin    // 2-bt counter ++ on each positive edge of 100Mhz clock
4
  clk_div <= clk_div + 2'b1;
5
end
6

7
always @ (posedge vga_clk) begin        //25Mhz clock
8
  ...

BTW:
Das ist ein offensichtlich hingebasteltes, zurechtgemurkstes 
Anfängerdesign, denn per Zähler werden in FPGAs keine Takte erzeugt. Ein 
brauchbares synchrones Design arbeitet mit Clock-Enables. Etwa so:
1
reg  vga_clken;  
2

3
always @ (posedge CLK50MHz) begin    // generate clock enable for 25 MHz
4
  vga_clken <= not vga_clken;
5
end
6

7
always @ (posedge CLK50MHz) begin    // the one and only clock!
8
  if (vga_clken==1) begin            // 25MHz VGA
9
    ...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren