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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [misc/] [apbvga.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003, Gaisler Research
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This program is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this program; if not, write to the Free Software
17
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
-----------------------------------------------------------------------------
19
-- Entity:      apbvga
20
-- File:        vga.vhd
21
-- Author:      Marcus Hellqvist
22
-- Description: VGA controller 
23
-----------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
library grlib;
28
use grlib.amba.all;
29
use grlib.stdlib.all;
30
use grlib.devices.all;
31
library techmap;
32
use techmap.gencomp.all;
33
library gaisler;
34
use gaisler.misc.all;
35
use gaisler.charrom_package.all;
36
 
37
entity apbvga is
38
  generic(
39
    memtech     : integer := DEFMEMTECH;
40
    pindex      : integer := 0;
41
    paddr       : integer := 0;
42
    pmask       : integer := 16#fff#
43
    );
44
  port( rst             : in std_ulogic;                        -- Global asynchronous reset
45
        clk             : in std_ulogic;                        -- Global clock
46
        vgaclk          : in std_ulogic;                        -- VGA clock
47
        apbi            : in apb_slv_in_type;
48
        apbo            : out apb_slv_out_type;
49
        vgao            : out apbvga_out_type
50
        );
51
end entity apbvga;
52
 
53
architecture rtl of apbvga is
54
 
55
type state_type is (s0,s1,s2);
56
 
57
 constant RAM_DEPTH     : integer := 12;
58
 constant RAM_DATA_BITS : integer := 8;
59
 constant MAX_FRAME     : std_logic_vector((RAM_DEPTH-1) downto 0):= X"B90";
60
 
61
type ram_out_type is record
62
 dataout2               : std_logic_vector((RAM_DATA_BITS -1) downto 0);
63
end record;
64
 
65
type vga_regs is record
66
 video_out      : std_logic_vector(23 downto 0);
67
 hsync          : std_ulogic;
68
 vsync          : std_ulogic;
69
 csync          : std_ulogic;
70
 hcnt           : std_logic_vector(9 downto 0);
71
 vcnt           : std_logic_vector(9 downto 0);
72
 blank          : std_ulogic;
73
 linecnt        : std_logic_vector(3 downto 0);
74
 h_video_on     : std_ulogic;
75
 v_video_on     : std_ulogic;
76
 pixel          : std_ulogic;
77
 state          : state_type;
78
 rombit         : std_logic_vector(2 downto 0);
79
 romaddr        : std_logic_vector(11 downto 0);
80
 ramaddr2       : std_logic_vector((RAM_DEPTH -1) downto 0);
81
 ramdatain2     : std_logic_vector((RAM_DATA_BITS -1) downto 0);
82
 wstartaddr     : std_logic_vector((RAM_DEPTH-1) downto 0);
83
 raddr          : std_logic_vector((RAM_DEPTH-1) downto 0);
84
 tmp            : std_logic_vector(RAM_DEPTH-1 downto 0);
85
end record;
86
 
87
type color_reg_type is record
88
 bgcolor        : std_logic_vector(23 downto 0);
89
 txtcolor       : std_logic_vector(23 downto 0);
90
end record;
91
 
92
type vmmu_reg_type is record
93
 waddr          : std_logic_vector((RAM_DEPTH-1) downto 0);
94
 wstartaddr     : std_logic_vector((RAM_DEPTH-1) downto 0);
95
 ramaddr1       : std_logic_vector((RAM_DEPTH -1) downto 0);
96
 ramdatain1     : std_logic_vector((RAM_DATA_BITS -1) downto 0);
97
 ramenable1     : std_ulogic;
98
 ramwrite1      : std_ulogic;
99
 color          : color_reg_type;
100
end record;
101
 
102
constant REVISION       : amba_version_type := 0;
103
constant pconfig        : apb_config_type := (
104
 
105
                        1 => apb_iobar(paddr, pmask));
106
constant hmax           : integer:= 799;
107
constant vmax           : integer:= 524;
108
constant hvideo         : integer:= 639;
109
constant vvideo         : integer:= 480;
110
constant hfporch        : integer:= 19;
111
constant vfporch        : integer:= 11;
112
constant hbporch        : integer:= 45;
113
constant vbporch        : integer:= 31;
114
constant hsyncpulse     : integer:= 96;
115
constant vsyncpulse     : integer:= 2;
116
constant char_height    : std_logic_vector(3 downto 0):="1100";
117
 
118
signal p,pin            : vmmu_reg_type;
119
signal ramo             : ram_out_type;
120
signal r,rin            : vga_regs;
121
signal romdata          : std_logic_vector(7 downto 0);
122
signal gnd, vcc         : std_ulogic;
123
 
124
begin
125
 
126
  gnd <= '0'; vcc <= '1';
127
 
128
  comb1: process(rst,r,p,romdata,ramo)
129
    variable v          : vga_regs;
130
  begin
131
    v:=r;
132
    v.wstartaddr := p.wstartaddr;
133
 
134
    -- horizontal counter
135
    if r.hcnt < conv_std_logic_vector(hmax,10) then
136
      v.hcnt := r.hcnt +1;
137
    else
138
      v.hcnt := (others => '0');
139
    end if;
140
    -- vertical counter
141
    if (r.vcnt >= conv_std_logic_vector(vmax,10)) and (r.hcnt >= conv_std_logic_vector(hmax,10)) then
142
      v.vcnt := (others => '0');
143
    elsif r.hcnt = conv_std_logic_vector(hmax,10) then
144
      v.vcnt := r.vcnt +1;
145
    end if;
146
    -- horizontal pixel out
147
    if r.hcnt <= conv_std_logic_vector(hvideo,10) then
148
      v.h_video_on := '1';
149
    else
150
      v.h_video_on := '0';
151
    end if;
152
    -- vertical pixel out
153
    if r.vcnt <= conv_std_logic_vector(vvideo,10) then
154
      v.v_video_on := '1';
155
    else
156
      v.v_video_on := '0';
157
    end if;
158
    -- generate hsync
159
    if (r.hcnt <= conv_std_logic_vector((hvideo+hfporch+hsyncpulse),10)) and
160
      (r.hcnt >= conv_std_logic_vector((hvideo+hfporch),10)) then
161
      v.hsync := '0';
162
    else
163
      v.hsync := '1';
164
    end if;
165
    -- generate vsync
166
    if (r.vcnt <= conv_std_logic_vector((vvideo+vfporch+vsyncpulse),10)) and
167
      (r.vcnt >= conv_std_logic_vector((vvideo+vfporch),10)) then
168
      v.vsync := '0';
169
    else
170
      v.vsync := '1';
171
    end if;
172
    --generate csync & blank
173
    v.csync := not (v.hsync xor v.vsync);
174
    v.blank := v.h_video_on and v.v_video_on;
175
 
176
    -- count line of character
177
    if v.hcnt = conv_std_logic_vector(hvideo,10) then
178
      if (r.linecnt = char_height) or (v.vcnt = conv_std_logic_vector(vmax,10)) then
179
        v.linecnt := (others => '0');
180
      else
181
        v.linecnt := r.linecnt +1;
182
      end if;
183
    end if;
184
 
185
    if v.blank = '1' then
186
      case r.state is
187
        when s0 =>      v.ramaddr2 := r.raddr;
188
                        v.raddr := r.raddr +1;
189
                        v.state := s1;
190
        when s1 =>      v.romaddr := v.linecnt & ramo.dataout2;
191
                        v.state := s2;
192
        when s2 =>      if r.rombit = "011" then
193
                          v.ramaddr2 := r.raddr;
194
                          v.raddr := r.raddr +1;
195
                        elsif r.rombit = "010" then
196
                          v.state := s1;
197
                        end if;
198
      end case;
199
      v.rombit := r.rombit - 1;
200
      v.pixel := romdata(conv_integer(r.rombit));
201
    end if;
202
 
203
    -- read from same address char_height times
204
    if v.raddr = (r.tmp + X"050") then
205
      if (v.linecnt < char_height) then
206
        v.raddr := r.tmp;
207
      elsif v.raddr(11 downto 4) = X"FF" then       --check for end of allowed memory(80x51)
208
        v.raddr := (others => '0');
209
        v.tmp := (others => '0');
210
      else
211
        v.tmp := r.tmp + X"050";
212
      end if;
213
    end if;
214
 
215
    if  v.v_video_on = '0'      then
216
      v.raddr := r.wstartaddr;
217
      v.tmp := r.wstartaddr;
218
      v.state := s0;
219
    end if;
220
 
221
    -- define pixel color                                       
222
    if v.pixel = '1'and  v.blank = '1' then
223
      v.video_out := p.color.txtcolor;
224
    else
225
      v.video_out := p.color.bgcolor;
226
    end if;
227
 
228
    if rst = '0' then
229
      v.hcnt := conv_std_logic_Vector(hmax,10);
230
      v.vcnt := conv_std_logic_Vector(vmax,10);
231
      v.v_video_on := '0';
232
      v.h_video_on := '0';
233
      v.hsync := '0';
234
      v.vsync := '0';
235
      v.csync := '0';
236
      v.blank := '0';
237
      v.linecnt := (others => '0');
238
      v.state := s0;
239
      v.rombit := "111";
240
      v.pixel := '0';
241
      v.video_out := (others => '0');
242
      v.raddr := (others => '0');
243
      v.tmp := (others => '0');
244
      v.ramaddr2 := (others => '0');
245
      v.ramdatain2 := (others => '0');
246
    end if;
247
 
248
    -- update register  
249
    rin <= v;
250
 
251
    -- drive outputs
252
    vgao.hsync <= r.hsync;
253
    vgao.vsync <= r.vsync;
254
    vgao.comp_sync <= r.csync;
255
    vgao.blank <= r.blank;
256
    vgao.video_out_r <= r.video_out(23 downto 16);
257
    vgao.video_out_g <= r.video_out(15 downto 8);
258
    vgao.video_out_b <= r.video_out(7 downto 0);
259
  end process;
260
 
261
 
262
  comb2: process(rst,r,p,apbi,ramo)
263
    variable v          : vmmu_reg_type;
264
    variable rdata : std_logic_vector(31 downto 0);
265
  begin
266
    v := p;
267
    v.ramenable1 := '0'; v.ramwrite1 := '0';
268
    rdata := (others => '0');
269
 
270
    case apbi.paddr(3 downto 2) is
271
      when "00" =>      if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
272
                           v.waddr := apbi.pwdata(19 downto 8);
273
                           v.ramdatain1 :=      apbi.pwdata(7 downto 0);
274
                           v.ramenable1 := '1';
275
                           v.ramwrite1  := '1';
276
                           v.ramaddr1 := apbi.pwdata(19 downto 8);
277
                         end if;
278
      when "01" =>      if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
279
                          v.color.bgcolor := apbi.pwdata(23 downto 0);
280
                        end if;
281
      when "10" =>      if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
282
                          v.color.txtcolor := apbi.pwdata(23 downto 0);
283
                        end if;
284
      when others =>    null;
285
    end case;
286
 
287
    if (p.waddr - p.wstartaddr) >= MAX_FRAME then
288
      if p.wstartaddr(11 downto 4) = X"FA" then    --last position of allowed memory
289
        v.wstartaddr := X"000";
290
      else
291
        v.wstartaddr := p.wstartaddr + X"050";
292
      end if;
293
    end if;
294
 
295
    if rst = '0' then
296
      v.waddr    := (others => '0');
297
      v.wstartaddr  := (others => '0');
298
      v.color.bgcolor := (others => '0');
299
      v.color.txtcolor := (others => '1');
300
    end if;
301
 
302
    --update registers
303
    pin <= v;
304
 
305
    --drive outputs
306
    apbo.prdata <= rdata;
307
    apbo.pindex <= pindex;
308
    apbo.pirq <= (others => '0');
309
  end process;
310
 
311
  apbo.pconfig <= pconfig;
312
 
313
  reg : process(clk)
314
  begin
315
    if clk'event and clk = '1' then
316
      p <= pin;
317
    end if;
318
  end process;
319
 
320
  reg2 : process(vgaclk)
321
  begin
322
    if vgaclk'event and vgaclk = '1' then
323
      r <= rin;
324
    end if;
325
  end process;
326
 
327
  rom0 : charrom port map(clk=>vgaclk, addr=>r.romaddr, data=>romdata);
328
  ram0 : syncram_2p generic map (tech => memtech, abits => RAM_DEPTH,
329
                                 dbits => RAM_DATA_BITS, sepclk => 1)
330
    port map (
331
      rclk => vgaclk, raddress => r.ramaddr2, dataout => ramo.dataout2, renable => vcc,
332
      wclk => clk, waddress => p.ramaddr1, datain => p.ramdatain1, write => p.ramwrite1
333
   );
334
--  ram0 : syncram_dp generic map (tech => memtech, abits => RAM_DEPTH, dbits => RAM_DATA_BITS)
335
--    port map ( clk1 => clk, address1 => p.ramaddr1, datain1 => p.ramdatain1, 
336
--      dataout1 => open, enable1 => p.ramenable1, write1 => p.ramwrite1, 
337
--      clk2 => vgaclk, address2 => r.ramaddr2, datain2 => r.ramdatain2, 
338
--      dataout2 => ramo.dataout2, enable2 => gnd, write2 => gnd);
339
-- pragma translate_off
340
    bootmsg : report_version
341
    generic map ("apbvga" & tost(pindex) & ": APB VGA module rev 0");
342
-- pragma translate_on
343
 
344
end architecture;

powered by: WebSVN 2.1.0

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