OpenCores
URL https://opencores.org/ocsvn/yavga/yavga/trunk

Subversion Repositories yavga

[/] [yavga/] [trunk/] [vhdl/] [vga_ctrl.vhd] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sandroamt
--------------------------------------------------------------------------------
2
----                                                                        ----
3
---- This file is part of the yaVGA project                                 ----
4
---- http://www.opencores.org/?do=project&who=yavga                         ----
5
----                                                                        ----
6
---- Description                                                            ----
7
---- Implementation of yaVGA IP core                                        ----
8
----                                                                        ----
9
---- To Do:                                                                 ----
10
----                                                                        ----
11
----                                                                        ----
12
---- Author(s):                                                             ----
13
---- Sandro Amato, sdroamt@netscape.net                                     ----
14
----                                                                        ----
15
--------------------------------------------------------------------------------
16
----                                                                        ----
17
---- Copyright (c) 2009, Sandro Amato                                       ----
18
---- All rights reserved.                                                   ----
19
----                                                                        ----
20
---- Redistribution  and  use in  source  and binary forms, with or without ----
21
---- modification,  are  permitted  provided that  the following conditions ----
22
---- are met:                                                               ----
23
----                                                                        ----
24
----     * Redistributions  of  source  code  must  retain the above        ----
25
----       copyright   notice,  this  list  of  conditions  and  the        ----
26
----       following disclaimer.                                            ----
27
----     * Redistributions  in  binary form must reproduce the above        ----
28
----       copyright   notice,  this  list  of  conditions  and  the        ----
29
----       following  disclaimer in  the documentation and/or  other        ----
30
----       materials provided with the distribution.                        ----
31
----     * Neither  the  name  of  SANDRO AMATO nor the names of its        ----
32
----       contributors may be used to  endorse or  promote products        ----
33
----       derived from this software without specific prior written        ----
34
----       permission.                                                      ----
35
----                                                                        ----
36
---- THIS SOFTWARE IS PROVIDED  BY THE COPYRIGHT  HOLDERS AND  CONTRIBUTORS ----
37
---- "AS IS"  AND  ANY EXPRESS OR  IMPLIED  WARRANTIES, INCLUDING,  BUT NOT ----
38
---- LIMITED  TO, THE  IMPLIED  WARRANTIES  OF MERCHANTABILITY  AND FITNESS ----
39
---- FOR  A PARTICULAR  PURPOSE  ARE  DISCLAIMED. IN  NO  EVENT  SHALL  THE ----
40
---- COPYRIGHT  OWNER  OR CONTRIBUTORS  BE LIABLE FOR ANY DIRECT, INDIRECT, ----
41
---- INCIDENTAL,  SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ----
42
---- BUT  NOT LIMITED  TO,  PROCUREMENT OF  SUBSTITUTE  GOODS  OR SERVICES; ----
43
---- LOSS  OF  USE,  DATA,  OR PROFITS;  OR  BUSINESS INTERRUPTION) HOWEVER ----
44
---- CAUSED  AND  ON  ANY THEORY  OF LIABILITY, WHETHER IN CONTRACT, STRICT ----
45
---- LIABILITY,  OR  TORT  (INCLUDING  NEGLIGENCE  OR OTHERWISE) ARISING IN ----
46
---- ANY  WAY OUT  OF THE  USE  OF  THIS  SOFTWARE,  EVEN IF ADVISED OF THE ----
47
---- POSSIBILITY OF SUCH DAMAGE.                                            ----
48
--------------------------------------------------------------------------------
49
 
50
library IEEE;
51
use IEEE.STD_LOGIC_1164.all;
52
use IEEE.STD_LOGIC_ARITH.all;
53
use IEEE.STD_LOGIC_UNSIGNED.all;
54
 
55
---- Uncomment the following library declaration if instantiating
56
---- any Xilinx primitives in this code.
57
--library UNISIM;
58
--use UNISIM.VComponents.all;
59
 
60
entity vga_ctrl is
61
--      generic (
62
--              g_H_SIZE : integer := 800;      -- horizontal size of input image, MAX 800
63
--              g_V_SIZE : integer := 600       -- vertical size of input image, MAX 600
64
--      );
65
 
66
  port (
67
    i_clk   : in std_logic;             -- must be 50MHz
68
    i_reset : in std_logic;
69
 
70
    -- background color (b/w)
71
    i_background : in std_logic;
72
 
73
    -- cross cursor 
74
    i_cursor_color : in std_logic_vector(2 downto 0);
75
    i_cursor_x     : in std_logic_vector(10 downto 0);
76
    i_cursor_y     : in std_logic_vector(9 downto 0);
77
 
78
    -- vga horizontal and vertical sync
79
    o_h_sync : out std_logic;
80
    o_v_sync : out std_logic;
81
 
82
    -- horizontal and vertical sync enable (allow power saving on ?VESA? Monitors)
83
    i_h_sync_en : in std_logic;
84
    i_v_sync_en : in std_logic;
85
 
86
    -- vga R G B signals (1 bit for each component (8 colors))
87
    o_r : out std_logic;
88
    o_g : out std_logic;
89
    o_b : out std_logic;
90
 
91
    -- chars RAM memory
92
    i_chr_addr : in  std_logic_vector(10 downto 0);
93
    i_chr_data : in  std_logic_vector(31 downto 0);
94
    o_chr_data : out std_logic_vector(31 downto 0);
95
    i_chr_clk  : in  std_logic;
96
    i_chr_en   : in  std_logic;
97
    i_chr_we   : in  std_logic_vector(3 downto 0);
98
    i_chr_rst  : in  std_logic;
99
 
100
    -- waveform RAM memory
101
    i_wav_d    : in std_logic_vector(15 downto 0);
102
    i_wav_we   : in std_logic;
103
    --i_clockA : IN std_logic;
104
    i_wav_addr : in std_logic_vector(9 downto 0)  --;
105
    --o_DOA : OUT std_logic_vector(15 downto 0)
106
    );
107
end vga_ctrl;
108
 
109
-- vga timings used
110
--                     0                                    TOT
111
-- ...-----------------|=============== PERIOD ==============|--...
112
--                     |                                     |
113
-- ...__           ___________________________           _______...
114
--      \_________/                           \_________/
115
--                                                                 
116
--      |         |    |               |      |         |    |
117
--      |         |    |               |      |         |    |
118
-- ...--|----S----|-F--|=======D=======|==B===|====S====|=F==|--...
119
--           Y      R          I          A        Y      R
120
--           N      O          S          C        N      O
121
--           C      N          P          K        C      N
122
--           T      T          L          P        T      T
123
--           I      P          T          O        I      P
124
--           M      O          I          R        M      O
125
--           E      R          M          C        E      R
126
--                  C          E          H               C
127
--                  H                                     H
128
--      |         |    |               |      |         |    |
129
--   ...|---------|----|===============|======|=========|====|--...
130
-- HPx:     120     56         800        63      120     56    px (h PERIOD = 1039 px)
131
-- VLn:     6       37         600        23      6       37    ln (v PERIOD = 666 ln)
132
--
133
-- and with 50Mhz dot clock (20ns dot time):
134
--      |         |    |               |      |         |    |
135
--   ...|---------|----|===============|======|=========|====|--...
136
--Htime:   2.4     1.12        16        1.26     2.4    1.12   usec  (h PERIOD = 20.78 usec) Hfreq 48123.195 Hz
137
--Vtime:  124.68  768.86     12468      477.94  124.68  768.68  usec  (v PERIOD = 13839.48 usec) Vfreq 72.257 Hz
138
 
139
architecture rtl of vga_ctrl is
140
 
141
  constant c_GRID_SIZE : std_logic_vector(6 downto 0) := "1111111";
142
  constant c_GRID_BIT  : integer                      := 6;
143
 
144
  --
145
  -- horizontal timing signals (in pixels count )
146
  constant c_H_DISPLAYpx    : integer := 800;
147
  constant c_H_BACKPORCHpx  : integer := 63;  -- also 60;
148
  constant c_H_SYNCTIMEpx   : integer := 120;
149
  constant c_H_FRONTPORCHpx : integer := 56;  --also 60;
150
  constant c_H_PERIODpx     : integer := c_H_DISPLAYpx +
151
                                         c_H_BACKPORCHpx +
152
                                         c_H_SYNCTIMEpx +
153
                                         c_H_FRONTPORCHpx;
154
 
155
  --
156
  -- vertical timing signals (in lines count)
157
  constant c_V_DISPLAYln    : integer := 600;
158
  constant c_V_BACKPORCHln  : integer := 23;
159
  constant c_V_SYNCTIMEln   : integer := 6;
160
  constant c_V_FRONTPORCHln : integer := 37;
161
  constant c_V_PERIODln     : integer := c_V_DISPLAYln +
162
                                         c_V_BACKPORCHln +
163
                                         c_V_SYNCTIMEln +
164
                                         c_V_FRONTPORCHln;
165
 
166
 
167
--  constant c_CHARS_WIDTH: std_logic_vector(2 downto 0) := "111";
168
--  constant c_CHARS_HEIGHT: std_logic_vector(3 downto 0) := "1111";
169
--  constant c_CHARS_COLS: std_logic_vector(6 downto 0) := "1100011";
170
--  constant c_CHARS_ROWS: std_logic_vector(5 downto 0) := "100100";
171
 
172
  --
173
  signal s_h_count      : std_logic_vector(10 downto 0);  -- horizontal pixel counter
174
  signal s_v_count      : std_logic_vector(9 downto 0);  -- verticalal line counter
175
  signal s_h_sync       : std_logic;    -- horizontal sync trigger
176
  signal s_h_sync_pulse : std_logic;    -- 1-clock pulse on sync trigger
177
 
178
  --
179
  -- signals for the charmaps Block RAM component...
180
  signal s_charmaps_ADDR : std_logic_vector (10 downto 0);
181
  signal s_charmaps_DO   : std_logic_vector (7 downto 0);
182
  signal s_charmaps_DO_l : std_logic_vector (7 downto 0);
183
 
184
  --
185
  -- to manage the outside display region's blanking
186
  signal s_display : std_logic;
187
  --
188
 
189
  --
190
  -- to manage the cursor position
191
  signal s_cursor_x : std_logic_vector(10 downto 0);
192
  signal s_cursor_y : std_logic_vector(9 downto 0);
193
 
194
  --
195
  -- to manage the chars  ram address and th ram ascii
196
  signal s_chars_ram_addr : std_logic_vector(12 downto 0);
197
  signal s_chars_ascii    : std_logic_vector(7 downto 0);
198
 
199
  --
200
  signal s_waveform_ADDRB : std_logic_vector (9 downto 0);
201
  signal s_waveform_DOB   : std_logic_vector (15 downto 0);
202
 
203
 
204
  -- charmaps
205
  -- |------| |-----------------|
206
  -- |   P  | | D D D D D D D D |
207
  -- |======| |=================|
208
  -- |   8  | | 7 6 5 4 3 2 1 0 |
209
  -- |======| |=================|
210
  -- | Free | | Row char pixels |
211
  -- |------| |-----------------|
212
  --
213
  component charmaps_rom
214
    port(
215
      i_clock : in  std_logic;
216
      i_ADDR  : in  std_logic_vector(10 downto 0);  -- 16 x ascii code (W=8 x H=16 pixel)
217
      o_DO    : out std_logic_vector(7 downto 0)    -- 8 bit char pixel
218
      );
219
  end component;
220
 
221
 
222
 
223
  -- wave form or video-line memory
224
  -- |------| |-------------------------------------------|
225
  -- | P  P | |  D  D  D |  D  D  D | D D D D D D D D D D |
226
  -- |======| |===========================================|
227
  -- |17 16 | | 15 14 13 | 12 11 10 | 9 8 7 6 5 4 3 2 1 0 |
228
  -- |======| |===========================================|
229
  -- | Free | |  Reserv. |  R  G  B |      vert. pos.     |
230
  -- |------| |-------------------------------------------|
231
  --
232
  component waveform_ram
233
    port(
234
      i_DIA    : in  std_logic_vector(15 downto 0);
235
      i_WEA    : in  std_logic;
236
      i_clockA : in  std_logic;
237
      i_ADDRA  : in  std_logic_vector(9 downto 0);
238
      --o_DOA : OUT std_logic_vector(15 downto 0);
239
      --
240
      i_DIB    : in  std_logic_vector(15 downto 0);
241
      i_WEB    : in  std_logic;
242
      i_clockB : in  std_logic;
243
      i_ADDRB  : in  std_logic_vector(9 downto 0);
244
      o_DOB    : out std_logic_vector(15 downto 0)
245
      );
246
  end component;
247
 
248
  component chars_RAM
249
    port(
250
      i_clock_rw : in  std_logic;
251
      i_EN_rw    : in  std_logic;
252
      i_WE_rw    : in  std_logic_vector(3 downto 0);
253
      i_ADDR_rw  : in  std_logic_vector(10 downto 0);
254
      i_DI_rw    : in  std_logic_vector(31 downto 0);
255
      o_DI_rw    : out std_logic_vector(31 downto 0);
256
      i_SSR      : in  std_logic;
257
      i_clock_r  : in  std_logic;
258
      i_ADDR_r   : in  std_logic_vector(12 downto 0);
259
      o_DO_r     : out std_logic_vector(7 downto 0)
260
      );
261
  end component;
262
 
263
 
264
  attribute U_SET                      : string;
265
  attribute U_SET of "u0_chars_RAM"    : label is "u0_chars_RAM_uset";
266
  attribute U_SET of "u1_charmaps_rom" : label is "u1_charmaps_rom_uset";
267
  attribute U_SET of "u2_waveform_ram" : label is "u2_waveform_ram_uset";
268
 
269
begin
270
 
271
  s_chars_ram_addr <= s_v_count(9 downto 4) & s_h_count(9 downto 3);
272
 
273
  u0_chars_RAM : chars_RAM port map(
274
    i_clock_rw => i_chr_clk,
275
    i_EN_rw    => i_chr_en,
276
    i_WE_rw    => i_chr_we,
277
    i_ADDR_rw  => i_chr_addr,
278
    i_DI_rw    => i_chr_data,
279
    o_DI_rw    => o_chr_data,
280
    i_SSR      => i_chr_rst,
281
    i_clock_r  => i_clk,
282
    i_ADDR_r   => s_chars_ram_addr,
283
    o_DO_r     => s_chars_ascii
284
    );
285
 
286
 
287
 
288
  u1_charmaps_rom : charmaps_rom port map(
289
    i_clock => i_clk,
290
    i_ADDR  => s_charmaps_ADDR,
291
    o_DO    => s_charmaps_DO
292
    );
293
 
294
  -- modify the charmaps address
295
  p_MGM_CHARMAPS_ADDR : process(i_clk)  --, i_reset) --, s_v_count, i_cursor_color)
296
  begin
297
    if rising_edge(i_clk) then
298
      if i_reset = '1' then                      -- sync reset
299
        s_charmaps_ADDR <= "01000000000";        -- (others => '0');
300
      else
301
        if (s_h_count(2 downto 0) = "110") then  -- each 8 h_count
302
          s_charmaps_DO_l <= s_charmaps_DO;
303
        end if;
304
        -- here start char 'a' ---v          v----- ascii code ------v   v-- vert char row --v
305
        --s_charmaps_ADDR <= "01000000000" + ( s_h_count(9 downto  3)    & s_v_count(3 downto 0) );
306
        s_charmaps_ADDR <= (s_chars_ascii(6 downto 0) & s_v_count(3 downto 0));
307
        -- here start char 'a' ---^          ^----- ascii code ------^   ^-- vert char row --^
308
      end if;
309
    end if;
310
  end process;
311
 
312
 
313
 
314
  u2_waveform_ram : waveform_ram port map(
315
    i_DIA    => i_wav_d,
316
    i_WEA    => i_wav_we,
317
    --i_clockA => i_clockA,
318
    i_clockA => i_clk,
319
    i_ADDRA  => i_wav_addr,
320
    --o_DOA => o_DOA,
321
    --
322
    i_DIB    => "1111111111111111",
323
    i_WEB    => '0',
324
    i_clockB => i_clk,
325
    -- i_ADDRB => s_waveform_ADDRB,
326
    i_ADDRB  => s_waveform_ADDRB,       --s_h_count(9 downto 0),
327
    o_DOB    => s_waveform_DOB
328
    );
329
 
330
  p_WaveFormAddr : process (i_clk)
331
  begin
332
    if rising_edge(i_clk) then
333
      s_waveform_ADDRB <= s_h_count(9 downto 0);
334
    end if;
335
  end process;
336
 
337
  p_pulse_on_hsync_falling : process(i_clk)
338
    variable v_h_sync1 : std_logic;
339
  begin
340
    if rising_edge(i_clk) then
341
      s_h_sync_pulse <= not s_h_sync and v_h_sync1;
342
      v_h_sync1      := s_h_sync;
343
    end if;
344
  end process;
345
 
346
 
347
  -- set the cursor position
348
  s_cursor_x <= i_cursor_x;             -- 400
349
  s_cursor_y <= i_cursor_y;             -- 300
350
 
351
  -- control the reset, increment and overflow of the horizontal pixel count
352
  p_H_PX_COUNT : process(i_clk)                          --, i_reset)
353
  begin
354
    if rising_edge(i_clk) then
355
      if i_reset = '1' or s_h_count = c_H_PERIODpx then  -- sync reset
356
        s_h_count <= (others => '0');
357
      else
358
        s_h_count <= s_h_count + 1;
359
      end if;
360
    end if;
361
  end process;
362
 
363
 
364
 
365
  p_V_LN_COUNT : process(i_clk)
366
  begin
367
    if rising_edge(i_clk) then
368
      if i_reset = '1' or s_v_count = c_V_PERIODln then  -- sync reset
369
        s_v_count <= (others => '0');
370
      elsif s_h_sync_pulse = '1' then
371
        s_v_count <= s_v_count + 1;
372
      end if;
373
    end if;
374
  end process;
375
 
376
  -- set the horizontal sync high time and low time according to the constants
377
  p_MGM_H_SYNC : process(i_clk)         --, i_reset)
378
  begin
379
    if rising_edge(i_clk) then
380
      if (s_h_count = c_H_DISPLAYpx + c_H_BACKPORCHpx) then
381
        s_h_sync <= '0';
382
      elsif (s_h_count = c_H_PERIODpx - c_H_FRONTPORCHpx) then
383
        s_h_sync <= '1';
384
      end if;
385
    end if;
386
  end process;
387
  o_h_sync <= s_h_sync and i_h_sync_en;
388
 
389
 
390
  p_MGM_V_SYNC : process(i_clk)         --, i_reset)
391
  begin
392
    --if falling_edge(i_clk) then
393
    if rising_edge(i_clk) then
394
      if i_v_sync_en = '0' or
395
        (s_v_count = (c_V_DISPLAYln + c_V_BACKPORCHln)) then
396
        o_v_sync <= '0';
397
      elsif (s_v_count = (c_V_PERIODln - c_V_FRONTPORCHln)) then  --and (s_h_sync_pulse = '1') then
398
        o_v_sync <= '1';
399
      end if;
400
    end if;
401
  end process;
402
 
403
  -- asserts the blaking signal (active low)
404
  p_MGM_BLANK : process (i_clk)         --, i_reset)
405
  begin
406
    if rising_edge(i_clk) then
407
      -- if we are outside the visible range on the screen then tell the RAMDAC to blank
408
      -- in this section by putting s_display low
409
      if not (s_h_count < c_H_DISPLAYpx and s_v_count < c_V_DISPLAYln) then
410
        s_display <= '0';
411
      else
412
        s_display <= '1';
413
      end if;
414
    end if;
415
  end process;
416
 
417
 
418
  -- generates the r g b signals and show the green cursor
419
  p_MGM_RGB : process (i_clk)  --, i_reset) --, i_cursor_color, s_display)
420
    variable v_previous_pixel : std_logic_vector(9 downto 0) := "0100101100";
421
  begin
422
    if rising_edge(i_clk) then          -- not async reset
423
      if i_reset = '1' then             -- sync reset
424
        o_r <= '0';
425
        o_g <= '0';
426
        o_b <= '0';
427
      else
428
        if s_display = '1' then         -- display zone
429
          if (
430
            (s_h_count = s_cursor_x) or (s_v_count = s_cursor_y) or
431
            (s_h_count(c_GRID_BIT downto 0) = c_GRID_SIZE(c_GRID_BIT downto 0)) or
432
            (s_v_count(c_GRID_BIT downto 0) = c_GRID_SIZE(c_GRID_BIT downto 0))
433
            )
434
            and (s_v_count(9) = '0')    -- < 512
435
          then  -- draw the cursor and/or WaveForm Grid references
436
            o_r <= i_cursor_color(2);
437
            o_g <= i_cursor_color(1);
438
            o_b <= i_cursor_color(0);
439
          elsif
440
            ((s_v_count(9 downto 0) >= s_waveform_DOB(9 downto 0)) and
441
             (s_v_count(9 downto 0) <= v_previous_pixel)
442
             ) or
443
            ((s_v_count(9 downto 0) <= s_waveform_DOB(9 downto 0)) and
444
             (s_v_count(9 downto 0) >= v_previous_pixel)
445
             )
446
          then                          -- draw the waveform pixel...
447
            o_r <= s_waveform_DOB(12) or s_waveform_DOB(15);  -- the "or" is only
448
            o_g <= s_waveform_DOB(11) or s_waveform_DOB(14);  -- to not warning
449
            o_b <= s_waveform_DOB(10) or s_waveform_DOB(13);  -- unused signals
450
          else                          -- draw the background and charmaps
451
            --if s_v_count > 512 then
452
            --FULL_SCREEN if (s_v_count(9) = '1') then -- >= 512
453
            case (s_h_count(2 downto 0)) is
454
              when "000"  => o_g <= s_charmaps_DO_l(7) xor i_background;
455
              when "001"  => o_g <= s_charmaps_DO_l(6) xor i_background;
456
              when "010"  => o_g <= s_charmaps_DO_l(5) xor i_background;
457
              when "011"  => o_g <= s_charmaps_DO_l(4) xor i_background;
458
              when "100"  => o_g <= s_charmaps_DO_l(3) xor i_background;
459
              when "101"  => o_g <= s_charmaps_DO_l(2) xor i_background;
460
              when "110"  => o_g <= s_charmaps_DO_l(1) xor i_background;
461
              when "111"  => o_g <= s_charmaps_DO_l(0) xor i_background;
462
              when others => o_g <= 'X';
463
                                        --when others => o_g <= i_background;
464
            end case;
465
            --FULL_SCREEN else
466
            --FULL_SCREEN   o_g <= i_background;
467
            --FULL_SCREEN end if;
468
            o_r <= i_background;
469
                                        --o_g <= i_background;
470
            o_b <= i_background;
471
          end if;
472
        else                            -- blank zone
473
          -- the blanking zone
474
          o_r <= '0';
475
          o_g <= '0';
476
          o_b <= '0';
477
        end if;  -- if s_display
478
        v_previous_pixel := s_waveform_DOB(9 downto 0);
479
      end if;  -- if i_reset
480
    end if;
481
  end process;
482
 
483
end rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.