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

Subversion Repositories pdp1

[/] [pdp1/] [trunk/] [rtl/] [vhdl/] [vga.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 yannv
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    22:05:52 11/22/2009 
6
-- Design Name: 
7
-- Module Name:    top - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.NUMERIC_STD.ALL;
23
 
24
---- Uncomment the following library declaration if instantiating
25
---- any Xilinx primitives in this code.
26
library UNISIM;
27
use UNISIM.VComponents.all;
28
 
29
entity vga is
30
    Port ( VGA_R : out  STD_LOGIC_VECTOR (3 downto 0);
31
           VGA_G : out  STD_LOGIC_VECTOR (3 downto 0);
32
           VGA_B : out  STD_LOGIC_VECTOR (3 downto 0);
33
           VGA_HSYNC : out  STD_LOGIC := '0';
34
           VGA_VSYNC : out  STD_LOGIC := '0';
35
           CLK_50M : in STD_LOGIC;
36
                          CLK_133M33 : in STD_LOGIC);
37
end vga;
38
 
39
architecture Behavioral of vga is
40
  signal VGA_CLK : std_logic;
41
 
42
        -- displayed stuff
43
  signal cell : std_logic := '1';
44
  signal fbwa, fbra : integer range 0 to 2048-1;
45
  signal fbwe : boolean := false;
46
  signal fbwd, fbrd : std_logic;
47
  type linebuffer is array (0 to 2048-1) of std_logic;
48
  signal pixels : linebuffer;
49
 
50
  type modeline is record
51
    pixelclock : real;     -- calculations for the DCM need to be done by hand
52
    hdisp      : positive;
53
         hsyncstart : positive;
54
         hsyncend   : positive;
55
         htotal     : positive;
56
         vdisp      : positive;
57
         vsyncstart : positive;
58
         vsyncend   : positive;
59
         vtotal     : positive;
60
         hpulse     : std_logic;  -- pulse level (i.e. '0' for -hsync, or '1' for +hsync)
61
         vpulse     : std_logic;
62
  end record modeline;
63
 
64
  -- Modelines taken from http://www.mythtv.org/wiki/Modeline_Database
65
 
66
  -- 640x480 VGA -- all -vsync -hsync
67
  constant VGA60: modeline := (25.18, 640, 656, 752, 800, 480, 490, 492, 525, '0', '0');  -- pitifully, 25 is as close as I get.
68
  constant VGA75: modeline := (31.50, 640, 656, 720, 840, 480, 481, 484, 500, '0', '0');  -- 50/27*17 ~ 31.48
69
  -- from VESA modepool
70
  constant SXGA60: modeline := (108.00, 1280, 1328, 1440, 1688, 1024, 1025, 1028, 1066, '1', '1'); -- 108 ~ 50/6*13 ~ 133.33/21*17
71
  -- 1920x1200@60Hz nvidia mode pool
72
  constant WUXGA60: modeline := (193.16, 1920, 2048, 2256, 2592, 1200, 1201, 1204, 1242, '1', '1'); -- 193.16 ~ 50/7*27 ~ 133.33/11*16
73
 
74
  constant mode: modeline := SXGA60;
75
  alias pixclksrc is CLK_133M33;
76
  constant pixclkperiod: real := 7.5;
77
  constant pixclkdiv: positive := 21;
78
  constant pixclkmul: positive := 17;
79
 
80
--  constant mode: modeline := VGA60;
81
--  alias pixclksrc is CLK_50M;
82
--  constant pixclkperiod: real := 20.0;
83
--  constant pixclkdiv: positive := 4;
84
--  constant pixclkmul: positive := 2;
85
 
86
  signal column: integer range 0 to mode.htotal-1 := 0;
87
  signal row: integer range 0 to mode.vtotal-1 := 0;
88
 
89
  signal vblank, hblank, linestart, framestart : boolean := false;
90
begin
91
   DCM_1 : DCM_SP
92
   generic map (                        -- synthesize 193.33MHz; we're a bit off.
93
      --CLKDV_DIVIDE => 2.0, --  Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
94
                           --     7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
95
      CLKFX_DIVIDE => pixclkdiv,   --  Can be any interger from 1 to 32
96
      CLKFX_MULTIPLY => pixclkmul, --  Can be any integer from 1 to 32
97
      --CLKIN_DIVIDE_BY_2 => FALSE, --  TRUE/FALSE to enable CLKIN divide by two feature
98
      CLKIN_PERIOD => pixclkperiod,--20.0, --  Specify period of input clock
99
      --CLKOUT_PHASE_SHIFT => "NONE", --  Specify phase shift of "NONE", "FIXED" or "VARIABLE" 
100
      CLK_FEEDBACK => "NONE",         --  Specify clock feedback of "NONE", "1X" or "2X" 
101
      --DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- "SOURCE_SYNCHRONOUS", "SYSTEM_SYNCHRONOUS" or
102
                                             --     an integer from 0 to 15
103
      --DLL_FREQUENCY_MODE => "LOW",     -- "HIGH" or "LOW" frequency mode for DLL
104
      DUTY_CYCLE_CORRECTION => TRUE, --  Duty cycle correction, TRUE or FALSE
105
      PHASE_SHIFT => 0,        --  Amount of fixed phase shift from -255 to 255
106
      STARTUP_WAIT => TRUE) --  Delay configuration DONE until DCM_SP LOCK, TRUE/FALSE
107
   port map (
108
      --CLK0 => open,     -- 0 degree DCM CLK ouptput
109
      --CLK180 => open, -- 180 degree DCM CLK output
110
      --CLK270 => open, -- 270 degree DCM CLK output
111
      --CLK2X => open,   -- 2X DCM CLK output
112
      --CLK2X180 => open, -- 2X, 180 degree DCM CLK out
113
      --CLK90 => open,   -- 90 degree DCM CLK output
114
      --CLKDV => open,   -- Divided DCM CLK out (CLKDV_DIVIDE)
115
      CLKFX => VGA_CLK,   -- DCM CLK synthesis out (M/D)
116
      --CLKFX180 => open, -- 180 degree CLK synthesis out
117
      --LOCKED => AWAKE, -- DCM LOCK status output
118
      --PSDONE => open, -- Dynamic phase adjust done output
119
      --STATUS => open, -- 8-bit DCM status bits output
120
      --CLKFB => open,   -- DCM clock feedback
121
      CLKIN => pixclksrc,   -- Clock input (from IBUFG, BUFG or DCM)
122
      --PSCLK => open,   -- Dynamic phase adjust clock input
123
      --PSEN => open,     -- Dynamic phase adjust enable input
124
      --PSINCDEC => open, -- Dynamic phase adjust increment/decrement
125
      RST => '0'        -- DCM asynchronous reset input
126
   );
127
 
128
  sync: process (VGA_CLK)
129
  begin
130
    if rising_edge(VGA_CLK) then
131
           linestart <= false;
132
           if column=mode.htotal-1 then
133
                  column <= 0;
134
                else
135
                  column <= column+1;
136
                end if;
137
                case column is
138
                  when mode.hdisp-1 =>
139
                    hblank <= true;
140
                  when mode.hsyncstart =>
141
                    VGA_HSYNC <= mode.hpulse;
142
          framestart <= false;
143
                    case row is
144
                      when mode.vsyncstart =>
145
                        VGA_VSYNC <= mode.vpulse;
146
                      when mode.vsyncend =>
147
                        VGA_VSYNC <= not mode.vpulse;
148
                           when mode.vdisp-1 =>
149
                             vblank <= true;
150
                           when mode.vtotal-1 =>
151
                             vblank <= false;
152
                                  framestart <= true;
153
                                when others =>
154
                                  null;
155
                    end case;
156
               if row=mode.vtotal-1 then
157
                      row <= 0;
158
                    else
159
                      row <= row+1;
160
                    end if;
161
                  when mode.hsyncend =>
162
                    VGA_HSYNC <= not mode.hpulse;
163
                  when mode.htotal-1 =>
164
                    linestart <= true;
165
                         hblank <= false;
166
                  when others =>
167
                    null;
168
                end case;
169
         end if;
170
  end process;
171
 
172
  memwr: process (VGA_CLK)
173
  begin  -- process memwr
174
    if VGA_CLK'event and VGA_CLK = '1' then  -- rising clock edge
175
      if fbwe then
176
        pixels(fbwa) <= fbwd;
177
      end if;
178
    end if;
179
  end process memwr;
180
  memrd: process (VGA_CLK)
181
  begin
182
    if rising_edge(VGA_CLK) then
183
      fbrd <= pixels(fbra);
184
    end if;
185
  end process memrd;
186
 
187
  -- purpose: calculates upcoming pixels
188
  -- type   : sequential
189
  -- inputs : VGA_CLK, vblank, newline
190
  -- outputs: cell
191
  wolfram: process (VGA_CLK)
192
    variable rule : unsigned(7 downto 0) := to_unsigned(30,8);
193
    variable x : integer range 0 to 2048-1 := 0;
194
    variable x0 : integer range 0 to 4 := 0;
195
    constant init : unsigned(0 to 4) := "00101";
196
    variable prev : unsigned(0 to 2) := "000";
197
  begin  -- process
198
    if rising_edge(VGA_CLK) then
199
      fbwe<=true;
200
      if linestart then
201
        x:=0;
202
        x0:=0;
203
      elsif x/=2048-1 then
204
        x:=x+1;
205
      end if;
206
      fbwa<=x;
207
                fbra<=x+4;
208
      if framestart then
209
        -- Wolfram rules:
210
        -- the three prior cells (left, self, right) are read as a binary number
211
        -- the rule number is converted to binary; each bit position corresponds
212
        -- to a configuration. thus, rule 34 is
213
        --  00100010 - only configuration 1 and 5 lead to state 1.
214
        -- that's 001 and 101, so the rule can only grow in one diagonal direction
215
                  cell <= '0';
216
                  fbwd <= '0';
217
                  -- initial conditions for different rules
218
                  case to_integer(rule) is
219
                    when 34 =>
220
            fbwd<=init(x0);
221
            cell <= init(x0);
222
          when others =>
223
                           if x=mode.hdisp/2 then
224
                          fbwd <= '1';
225
                               cell <= '1';
226
            end if;
227
                  end case;
228
        if x0=4 then
229
          x0:=0;
230
        else
231
          x0:=x0+1;
232
        end if;
233
        prev:="0"&init(0 to 1);         -- first two pixels will be strange :/
234
      else
235
                  fbwd<=rule(to_integer(prev));
236
                  cell<=rule(to_integer(prev));
237
        prev(0 to 1):=prev(1 to 2);
238
        if x<mode.hdisp-1 then
239
          prev(2):=fbrd;
240
        else
241
          prev(2):='1';
242
        end if;
243
      end if;
244
    end if;
245
  end process wolfram;
246
 
247
   -- purpose: output a signal to the VGA port
248
   -- type   : sequential
249
   -- inputs : VGA_CLK
250
   -- outputs: VGA_R, VGA_G, VGA_B, VGA_HSYNC, VGA_VSYNC
251
   vgaout: process (VGA_CLK)
252
          variable vdisparea : boolean := false;
253
   begin  -- process vgaout
254
     if rising_edge(VGA_CLK) then
255
       -- pixel value output
256
       if not (hblank or vblank) then
257
         case column is
258
           when 0|mode.hdisp-1 =>
259
             VGA_R <= (others => '1');
260
             VGA_G <= (others => '1');
261
             VGA_B <= (others => '1');
262
           when others =>
263
             case row is
264
               when 0|mode.vdisp-1 =>
265
                 VGA_R <= (others => '1');
266
                 VGA_G <= (others => '1');
267
                 VGA_B <= (others => '1');
268
               when others =>
269
                 VGA_R <= (others => cell);
270
                 VGA_G <= (others => cell);
271
                 VGA_B <= (others => cell);
272
             end case;
273
         end case;
274
       else
275
         VGA_R <= (others => '0');
276
         VGA_G <= (others => '0');
277
         VGA_B <= (others => '0');
278
       end if;
279
     end if;
280
   end process vgaout;
281
 
282
end Behavioral;
283
 

powered by: WebSVN 2.1.0

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