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

Subversion Repositories vg_z80_sbc

[/] [vg_z80_sbc/] [trunk/] [rtl/] [vga80x40.vhd] - Blame information for rev 36

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

Line No. Rev Author Line
1 3 hharte
-- Hi Emacs, this is -*- mode: vhdl; -*-
2
----------------------------------------------------------------------------------------------------
3
--
4
-- Monocrome Text Mode Video Controller VHDL Macro
5
-- 80x40 characters. Pixel resolution is 640x480/60Hz
6
-- 
7
-- Copyright (c) 2007 Javier Valcarce García, javier.valcarce@gmail.com
8 18 hharte
-- $Id: vga80x40.vhd,v 1.2 2008-12-13 20:18:29 hharte Exp $
9 3 hharte
--
10
----------------------------------------------------------------------------------------------------
11
-- This program is free software: you can redistribute it and/or modify
12
-- it under the terms of the GNU Lesser General Public License as published by
13
-- the Free Software Foundation, either version 3 of the License, or
14
-- (at your option) any later version.
15
 
16
-- This program is distributed in the hope that it will be useful,
17
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
-- GNU Lesser General Public License for more details.
20
--
21
-- You should have received a copy of the GNU Lesser General Public License
22
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
----------------------------------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
use ieee.numeric_std.all;
28
 
29
 
30
entity vga80x40 is
31
generic (
32
        font_height      : integer := 10;               -- number of pixels in font height
33
        text_height      : integer := 1         -- set to 1 for 80x48, 2 for 80x24
34
);
35
  port (
36
    reset       : in  std_logic;
37
    clk25MHz    : in  std_logic;
38
    TEXT_A      : out std_logic_vector(11 downto 0); -- text buffer
39
    TEXT_D      : in  std_logic_vector(07 downto 0);
40
         FONT_A      : out std_logic_vector(11 downto 0); -- font buffer
41
         FONT_D      : in  std_logic_vector(07 downto 0);
42
         --
43
         ocrx        : in  std_logic_vector(07 downto 0); -- OUTPUT regs
44
    ocry        : in  std_logic_vector(07 downto 0);
45
    octl        : in  std_logic_vector(07 downto 0);
46
    --
47
    R           : out std_logic;
48
    G           : out std_logic;
49
    B           : out std_logic;
50
    hsync       : out std_logic;
51
    vsync       : out std_logic
52
    );
53
end vga80x40;
54
 
55 18 hharte
 
56
 
57 3 hharte
architecture rtl of vga80x40 is
58
 
59
  signal R_int : std_logic;
60
  signal G_int : std_logic;
61
  signal B_int : std_logic;
62
  signal hsync_int : std_logic;
63
  signal vsync_int : std_logic;
64
 
65
  signal blank : std_logic;
66
  signal hctr  : integer range 793 downto 0;
67
  signal vctr  : integer range 524 downto 0;
68
  -- character/pixel position on the screen
69
  signal scry  : integer range 039 downto 0;  -- chr row   < 40 (6 bits)
70
  signal scrx  : integer range 079 downto 0;  -- chr col   < 80 (7 bits)
71
  signal chry  : integer range (font_height * text_height)-1 downto 0;  -- chr high  < 12 (5 bits)
72
  signal chrx  : integer range 007 downto 0;  -- chr width < 08 (3 bits)
73
 
74
  signal losr_ce : std_logic;
75
  signal losr_ld : std_logic;
76
  signal losr_do : std_logic;
77
  signal y       : std_logic;  -- character luminance pixel value (0 or 1)
78
 
79
  -- control io register
80
  signal ctl       : std_logic_vector(7 downto 0);
81
  signal vga_en    : std_logic;
82
  signal cur_en    : std_logic;
83
  signal cur_mode  : std_logic;
84
  signal cur_blink : std_logic;
85
  signal ctl_r     : std_logic;
86
  signal ctl_g     : std_logic;
87
  signal ctl_b     : std_logic;
88
 
89
  component ctrm
90
    generic (
91
      M : integer := 08);
92
    port (
93
      reset : in  std_logic;            -- asyncronous reset
94
      clk   : in  std_logic;
95
      ce    : in  std_logic;            -- enable counting
96
      rs    : in  std_logic;            -- syncronous reset
97
      do    : out integer range (M-1) downto 0
98
      );
99
  end component;
100
 
101
  component losr
102
    generic (
103
      N : integer := 04);
104
    port (
105
      reset : in  std_logic;
106
      clk   : in  std_logic;
107
      load  : in  std_logic;
108
      ce    : in  std_logic;
109
      do    : out std_logic;
110
      di    : in  std_logic_vector(N-1 downto 0));
111
  end component;
112
 
113
begin
114
 
115
-------------------------------------------------------------------------------
116
-------------------------------------------------------------------------------  
117
-- hsync generator, initialized with '1'
118
  process (reset, clk25MHz)
119
  begin
120
    if reset = '1' then
121
      hsync_int <= '1';
122
    elsif rising_edge(clk25MHz) then
123
 
124
      if (hctr > 663) and (hctr < 757) then
125
        hsync_int <= '0';
126
      else
127
        hsync_int <= '1';
128
      end if;
129
 
130
    end if;
131
  end process;
132
 
133
 
134
-------------------------------------------------------------------------------
135
-------------------------------------------------------------------------------
136
-- vsync generator, initialized with '1'
137
  process (reset, clk25MHz)
138
  begin
139
    if reset = '1' then
140
      vsync_int <= '1';
141
    elsif rising_edge(clk25MHz) then
142
      if (vctr > 499) and (vctr < 502) then
143
        vsync_int <= '0';
144
      else
145
        vsync_int <= '1';
146
      end if;
147
    end if;
148
  end process;
149
 
150
-------------------------------------------------------------------------------
151
-------------------------------------------------------------------------------  
152
-- Blank signal, 0 = no draw, 1 = visible/draw zone   
153
 
154 18 hharte
  blank <= '0' when (hctr < 8) or (hctr > 647) or (vctr > 479) else '1';
155
 
156 3 hharte
-------------------------------------------------------------------------------
157
-------------------------------------------------------------------------------  
158
-- flip-flips for sync of R, G y B signal, initialized with '0'
159
  process (reset, clk25MHz)
160
  begin
161
    if reset = '1' then
162
      R <= '0';
163
      G <= '0';
164
      B <= '0';
165
    elsif rising_edge(clk25MHz) then
166
      R <= R_int;
167
      G <= G_int;
168
      B <= B_int;
169
    end if;
170
  end process;
171
 
172
 
173
-------------------------------------------------------------------------------
174
-------------------------------------------------------------------------------  
175
-------------------------------------------------------------------------------
176
-------------------------------------------------------------------------------
177
  -- Control register. Individual control signal
178
  cur_mode  <= octl(4);
179
  cur_blink <= octl(5);
180
  cur_en    <= octl(6);
181
  vga_en    <= octl(7);
182
  ctl_r     <= octl(2);
183
  ctl_g     <= octl(1);
184
  ctl_b     <= octl(0);
185
 
186
        -- counters, hctr, vctr, srcx, srcy, chrx, chry
187
        -- TODO: OPTIMIZE THIS
188
  counters : block
189
    signal hctr_ce : std_logic;
190
    signal hctr_rs : std_logic;
191
    signal vctr_ce : std_logic;
192
    signal vctr_rs : std_logic;
193
 
194
    signal chrx_ce : std_logic;
195
    signal chrx_rs : std_logic;
196
    signal chry_ce : std_logic;
197
    signal chry_rs : std_logic;
198
    signal scrx_ce : std_logic;
199
    signal scrx_rs : std_logic;
200
    signal scry_ce : std_logic;
201
    signal scry_rs : std_logic;
202
 
203
    signal hctr_639 : std_logic;
204
    signal vctr_479 : std_logic;
205
    signal chrx_007 : std_logic;
206
    signal chry_011 : std_logic;
207
    signal scrx_079 : std_logic;
208
 
209
    -- RAM read, ROM read
210
    signal ram_tmp : integer range 3200 downto 0;  --12 bits
211
    signal rom_tmp : integer range 3070 downto 0;
212
 
213
  begin
214
 
215
    U_HCTR : ctrm generic map (M => 794) port map (
216
         reset =>reset, clk=>clk25MHz, ce =>hctr_ce, rs =>hctr_rs, do => hctr);
217
 
218
    U_VCTR : ctrm generic map (M => 525) port map (reset, clk25MHz, vctr_ce, vctr_rs, vctr);
219
 
220
    hctr_ce <= '1';
221
    hctr_rs <= '1' when hctr = 793 else '0';
222
    vctr_ce <= '1' when hctr = 663 else '0';
223
    vctr_rs <= '1' when vctr = 524 else '0';
224
 
225
    U_CHRX: ctrm generic map (M => 008) port map (reset, clk25MHz, chrx_ce, chrx_rs, chrx);
226
    U_CHRY: ctrm generic map (M => (font_height * text_height)) port map (reset, clk25MHz, chry_ce, chry_rs, chry);
227
    U_SCRX: ctrm generic map (M => 080) port map (reset, clk25MHz, scrx_ce, scrx_rs, scrx);
228
    U_SCRY: ctrm generic map (M => 040) port map (reset, clk25MHz, scry_ce, scry_rs, scry);
229
 
230
    hctr_639 <= '1' when hctr = 639 else '0';
231
    vctr_479 <= '1' when vctr = 479 else '0';
232
    chrx_007 <= '1' when chrx = 007 else '0';
233
    chry_011 <= '1' when chry = (font_height * text_height)-1 else '0';
234
    scrx_079 <= '1' when scrx = 079 else '0';
235
 
236
    chrx_rs <= chrx_007 or hctr_639;
237
    chry_rs <= chry_011 or vctr_479;
238
    scrx_rs <= hctr_639;
239
    scry_rs <= vctr_479;
240
 
241
    chrx_ce <= '1' and blank;
242
    scrx_ce <= chrx_007;
243
    chry_ce <= hctr_639 and blank;
244
    scry_ce <= chry_011 and hctr_639;
245
 
246 18 hharte
    ram_tmp <= scry * 80 + scrx;
247 3 hharte
 
248
    TEXT_A <= std_logic_vector(TO_UNSIGNED(ram_tmp, 12));
249
 
250 18 hharte
    rom_tmp <= TO_INTEGER(unsigned(TEXT_D)) * font_height + (chry/text_height);
251 3 hharte
    FONT_A <= std_logic_vector(TO_UNSIGNED(rom_tmp, 12));
252
 
253
  end block;
254
-------------------------------------------------------------------------------
255
-------------------------------------------------------------------------------
256
-------------------------------------------------------------------------------
257
 
258
  U_LOSR : losr generic map (N => 8)
259
    port map (reset, clk25MHz, losr_ld, losr_ce, losr_do, FONT_D);
260
 
261
  losr_ce <= blank;
262
  losr_ld <= '1' when (chrx = 007) else '0';
263
 
264
  -- video out, vga_en control signal enable/disable vga signal
265
  R_int <= (ctl_r and y) and blank;
266
  G_int <= (ctl_g and y) and blank;
267
  B_int <= (ctl_b and y) and blank;
268
 
269
  hsync <= hsync_int and vga_en;
270
  vsync <= vsync_int and vga_en;
271
 
272
-------------------------------------------------------------------------------
273
-------------------------------------------------------------------------------
274
-------------------------------------------------------------------------------
275
 
276
  -- Hardware Cursor
277
  hw_cursor : block
278
    signal small   : std_logic;
279
    signal curen2  : std_logic;
280
    signal slowclk : std_logic;
281
    signal curpos  : std_logic;
282
    signal yint    : std_logic;
283
    signal crx_tmp : integer range 079 downto 0;
284
    signal cry_tmp : integer range 039 downto 0;
285
    signal crx     : integer range 079 downto 0;
286
    signal cry     : integer range 039 downto 0;
287
    signal counter : unsigned(22 downto 0);
288
  begin
289
 
290
    -- slowclk for blink hardware cursor
291
    counter <= counter + 1 when rising_edge(clk25MHz);
292
         slowclk <= counter(22); --2.98Hz
293
 
294
    crx <= TO_INTEGER(unsigned(ocrx(6 downto 0)));
295
    cry <= TO_INTEGER(unsigned(ocry(5 downto 0)));
296
 
297
    --
298
    curpos <= '1' when (scry = cry) and (scrx = crx) else '0';
299
    small  <= '1' when (chry > 8)                    else '0';
300
    curen2 <= (slowclk or (not cur_blink)) and cur_en;
301
    yint   <= '1' when cur_mode = '0'                else small;
302
    y      <= (yint and curpos and curen2) xor losr_do;
303
 
304
  end block;
305
 
306
end rtl;

powered by: WebSVN 2.1.0

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