Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / fpga / ctrls / vga /

vga_ctrl.vhd

   1  -- vga_ctrl.vhd: VGA base controller
   2  -- Copyright (C) 2006 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Ladislav Capka <xcapka01 AT @stud.fit.vutbr.cz>
   5  --
   6  -- LICENSE TERMS
   7  --
   8  -- Redistribution and use in source and binary forms, with or without
   9  -- modification, are permitted provided that the following conditions
  10  -- are met:
  11  -- 1. Redistributions of source code must retain the above copyright
  12  --    notice, this list of conditions and the following disclaimer.
  13  -- 2. Redistributions in binary form must reproduce the above copyright
  14  --    notice, this list of conditions and the following disclaimer in
  15  --    the documentation and/or other materials provided with the
  16  --    distribution.
  17  -- 3. All advertising materials mentioning features or use of this software
  18  --    or firmware must display the following acknowledgement:
  19  --
  20  --      This product includes software developed by the University of
  21  --      Technology, Faculty of Information Technology, Brno and its
  22  --      contributors.
  23  --
  24  -- 4. Neither the name of the Company nor the names of its contributors
  25  --    may be used to endorse or promote products derived from this
  26  --    software without specific prior written permission.
  27  --
  28  -- This software or firmware is provided ``as is'', and any express or implied
  29  -- warranties, including, but not limited to, the implied warranties of
  30  -- merchantability and fitness for a particular purpose are disclaimed.
  31  -- In no event shall the company or contributors be liable for any
  32  -- direct, indirect, incidental, special, exemplary, or consequential
  33  -- damages (including, but not limited to, procurement of substitute
  34  -- goods or services; loss of use, data, or profits; or business
  35  -- interruption) however caused and on any theory of liability, whether
  36  -- in contract, strict liability, or tort (including negligence or
  37  -- otherwise) arising in any way out of the use of this software, even
  38  -- if advised of the possibility of such damage.
  39  --
  40  -- $Id$
  41  --
  42  --
  43  
  44  -- SYNTH-ISE-8.1: slices=87, slicesFF=34, 4luts=159
  45  -- SYNTH-ISE-8.2: slices=81, slicesFF=31, 4luts=152
  46  library ieee;
  47  use ieee.std_logic_1164.all;
  48  use ieee.std_logic_arith.conv_std_logic_vector;
  49  use ieee.std_logic_unsigned.all;
  50  use work.vga_controller_cfg.all;
  51  
  52  entity vga_controller is
  53     generic (
  54        REQ_DELAY : natural := 1
  55        );
  56     port (
  57        -- Hodiny + reset
  58        CLK     : in std_logic;
  59        RST     : in std_logic;
  60        ENABLE  : in std_logic;
  61  
  62        -- Nastaveni rozliseni (popis v VGA_CONFIG.VHD)
  63        -- Pozor: Hodnota musi zustat stale platna!
  64        MODE    : in std_logic_vector(60 downto 0);
  65  
  66        -- Vstup / pozadavek
  67        DATA_RED    : in  std_logic_vector(2 downto 0);
  68        DATA_GREEN  : in  std_logic_vector(2 downto 0);
  69        DATA_BLUE   : in  std_logic_vector(2 downto 0);
  70        ADDR_COLUMN : out std_logic_vector(11 downto 0);
  71        ADDR_ROW    : out std_logic_vector(11 downto 0);
  72  
  73        -- Vystup na VGA
  74        VGA_RED   : out std_logic_vector(2 downto 0);
  75        VGA_GREEN : out std_logic_vector(2 downto 0);
  76        VGA_BLUE  : out std_logic_vector(2 downto 0);
  77        VGA_HSYNC : out std_logic;
  78        VGA_VSYNC : out std_logic;
  79  
  80        -- H/V Status
  81        STATUS_H  : out vga_hfsm_state;
  82        STATUS_V  : out vga_vfsm_state
  83        );
  84  end vga_controller;
  85  
  86  architecture arch_vga_controller of vga_controller is
  87  
  88     -- Aktivace radice
  89     signal ienable     : std_logic := '1';
  90  
  91     -- Vnitrni reset radice
  92     signal ireset      : std_logic := '1';
  93  
  94     -- Horizontalni hodnoty
  95     signal h_pixels    : std_logic_vector(11 downto 0);
  96     signal h_syncstart : std_logic_vector(6 downto 0);
  97     signal h_syncend   : std_logic_vector(6 downto 0);
  98     signal h_period    : std_logic_vector(6 downto 0);
  99  
 100     -- Vertikalni hodnoty
 101     signal v_lines     : std_logic_vector(11 downto 0);
 102     signal v_syncstart : std_logic_vector(5 downto 0);
 103     signal v_syncend   : std_logic_vector(3 downto 0);
 104     signal v_period    : std_logic_vector(5 downto 0);
 105  
 106     -- MX pro citace
 107     signal req_delay_mx   : std_logic;
 108     signal h_pixels_mx    : std_logic;
 109     signal v_lines_mx     : std_logic;
 110     signal h_syncstart_mx : std_logic;
 111     signal h_syncend_mx   : std_logic;
 112     signal h_period_mx    : std_logic;
 113     signal v_syncstart_mx : std_logic;
 114     signal v_syncend_mx   : std_logic;
 115     signal v_period_mx    : std_logic;
 116  
 117     -- H/V citac
 118     signal hcnt        : std_logic_vector(11 downto 0) := (others => '0');
 119     signal vcnt        : std_logic_vector(11 downto 0) := (others => '0');
 120  
 121     -- Reset H/V citace
 122     signal hcnt_reset  : std_logic := '1';
 123     signal vcnt_reset  : std_logic := '1';
 124  
 125     -- Aktivace V citace
 126     signal vcnt_en     : std_logic := '0';
 127  
 128     -- Aktivace vstupu/vystupu VGA radice
 129     signal out_en      : std_logic_vector(1 downto 0);
 130     signal req_en      : std_logic_vector(1 downto 0);
 131     signal use_rqdelay : std_logic := '0';
 132  
 133     -- H/V synchronizacni puls
 134     signal hsync_en    : std_logic := '0';
 135     signal vsync_en    : std_logic := '0';
 136  
 137     -- Stavy FSMs
 138     signal hfsm_cst    : vga_hfsm_state;
 139     signal hfsm_nst    : vga_hfsm_state;
 140     signal vfsm_cst    : vga_vfsm_state;
 141     signal vfsm_nst    : vga_vfsm_state;
 142  
 143  begin
 144  
 145     -- Nastaveni
 146     h_pixels    <= MODE(60 downto 49);
 147     v_lines     <= MODE(48 downto 37);
 148     h_syncstart <= MODE(36 downto 30);
 149     h_syncend   <= MODE(29 downto 23);
 150     h_period    <= MODE(22 downto 16);
 151     v_syncstart <= MODE(15 downto 10);
 152     v_syncend   <= MODE(9 downto 6);
 153     v_period    <= MODE(5 downto 0);
 154  
 155     STATUS_H  <= hfsm_cst;
 156     STATUS_V  <= vfsm_cst;
 157  
 158     VGA_RED   <= DATA_RED   when out_en = "11" else (others => '0');
 159     VGA_GREEN <= DATA_GREEN when out_en = "11" else (others => '0');
 160     VGA_BLUE  <= DATA_BLUE  when out_en = "11" else (others => '0');
 161     VGA_HSYNC <= not hsync_en;
 162     VGA_VSYNC <= not vsync_en;
 163  
 164     ADDR_COLUMN <= hcnt when req_en = "11" else (others => '0');
 165     ADDR_ROW    <= vcnt when req_en(1) = '1' else (others => '0');
 166  
 167     ireset <= '1' when (RST = '1') or (ienable = '0') else '0';
 168     use_rqdelay <= '0' when REQ_DELAY = 0 else '1';
 169  
 170     enable_sync: process (CLK)
 171     begin
 172        if CLK'event and CLK = '1' then
 173           ienable <= ENABLE;
 174        end if;
 175     end process;
 176  
 177     fsm_control: process(CLK, ireset)
 178     begin
 179        if (ireset = '1') then
 180           hfsm_cst <= hstDisabled;
 181           vfsm_cst <= vstPrepare;
 182        elsif CLK'event and CLK = '1' then
 183           hfsm_cst <= hfsm_nst; -- Horizontal FSM
 184           vfsm_cst <= vfsm_nst; -- Vertical FSM
 185        end if;
 186     end process;
 187  
 188     line_fsm: process(hfsm_cst, hcnt, ireset, req_delay_mx, h_pixels_mx, h_syncstart_mx, h_syncend_mx, h_period_mx)
 189     begin
 190        -- Default
 191        hfsm_nst   <= hstDisabled;  -- Dalsi stav = radic neaktivni
 192        vcnt_en    <= '0';          -- V citac zastaven
 193        out_en(0)  <= '0';          -- VGA vystup neaktivni
 194        req_en(0)  <= '0';          -- Vstupni pozadavky neaktivni
 195        hsync_en   <= '0';          -- H sync neaktivni
 196        hcnt_reset <= '0';          -- Neresetujeme citac
 197  
 198        case hfsm_cst is
 199           when hstDisabled => -- Radic neaktivni
 200                hcnt_reset <= '1';
 201                if ireset = '0' then
 202                   hfsm_nst <= hstPrepare;
 203                else
 204                   hfsm_nst <= hstDisabled;
 205                end if;
 206  
 207           when hstPrepare => -- Citace online
 208                hcnt_reset <= '1';
 209                if use_rqdelay = '0' then
 210                   hfsm_nst  <= hstDraw;
 211                else
 212                   hfsm_nst  <= hstRequestOnly;
 213                end if;
 214  
 215           when hstRequestOnly => -- Cekani REQ_DELAY pred kreslenim
 216                req_en(0) <= '1';
 217                if req_delay_mx = '1' then
 218                   hfsm_nst <= hstDraw;
 219                else
 220                   hfsm_nst <= hstRequestOnly;
 221                end if;
 222  
 223           when hstDraw => -- Kresleni
 224                out_en(0) <= '1';
 225                req_en(0) <= '1';
 226                if h_pixels_mx = '1' then
 227                   hcnt_reset <= '1';
 228                   if use_rqdelay = '0' then
 229                      hfsm_nst  <= hstWaitSync;
 230                   else
 231                      hfsm_nst  <= hstDrawOnly;
 232                   end if;
 233                else
 234                   hfsm_nst <= hstDraw;
 235                end if;
 236  
 237           when hstDrawOnly => -- Konec kresleni se spozdenim REQ_DELAY
 238                out_en(0) <= '1';
 239                if req_delay_mx = '1' then
 240                   hcnt_reset <= '1';
 241                   hfsm_nst <= hstWaitSync;
 242                else
 243                   hfsm_nst <= hstDrawOnly;
 244                end if;
 245  
 246           when hstWaitSync => -- Cekani pred H sync
 247                if h_syncstart_mx = '1' then
 248                   hcnt_reset <= '1';
 249                   hfsm_nst <= hstSync;
 250                else
 251                   hfsm_nst <= hstWaitSync;
 252                end if;
 253  
 254           when hstSync => -- H synchronizacni pulz
 255                hsync_en <= '1';
 256                if h_syncend_mx = '1' then
 257                   hcnt_reset <= '1';
 258                   vcnt_en  <= '1';
 259                   hfsm_nst <= hstWaitPeriod;
 260                else
 261                   hfsm_nst <= hstSync;
 262                end if;
 263  
 264           when hstWaitPeriod => -- Cekani po H sync
 265                if h_period_mx = '1' then
 266                   hcnt_reset <= '1';
 267                   if use_rqdelay = '0' then
 268                      hfsm_nst  <= hstDraw;
 269                   else
 270                      hfsm_nst  <= hstRequestOnly;
 271                   end if;
 272                else
 273                   hfsm_nst <= hstWaitPeriod;
 274                end if;
 275        end case;
 276     end process;
 277  
 278     frame_fsm: process(vfsm_cst, vcnt, ireset, v_lines_mx, v_syncstart_mx, v_syncend_mx, v_period_mx)
 279     begin
 280        vfsm_nst   <= vstPrepare;
 281        out_en(1)  <= '0';
 282        req_en(1)  <= '0';
 283        vcnt_reset <= '0';
 284        vsync_en   <= '0';
 285  
 286        case vfsm_cst is
 287           when vstPrepare => -- Start
 288                vcnt_reset <= '1';
 289                req_en(1)  <= '1';
 290                out_en(1)  <= '1';
 291                vfsm_nst   <= vstDraw;
 292  
 293           when vstDraw => -- Kresleni
 294                if v_lines_mx = '1' then
 295                   vcnt_reset <= '1';
 296                   vfsm_nst   <= vstWaitSync;
 297                else
 298                   req_en(1)  <= '1';
 299                   out_en(1)  <= '1';
 300                   vfsm_nst   <= vstDraw;
 301                end if;
 302  
 303           when vstWaitSync => -- Cekani pred V sync
 304                if v_syncstart_mx = '1' then
 305                   vcnt_reset <= '1';
 306                   vsync_en   <= '1';
 307                   vfsm_nst   <= vstSync;
 308                else
 309                   vfsm_nst <= vstWaitSync;
 310                end if;
 311  
 312           when vstSync => -- V synchronizacni pulz
 313                if v_syncend_mx = '1' then
 314                   vcnt_reset <= '1';
 315                   vsync_en <= '0';
 316                   vfsm_nst <= vstWaitPeriod;
 317                else
 318                   vsync_en <= '1';
 319                   vfsm_nst <= vstSync;
 320                end if;
 321  
 322           when vstWaitPeriod => -- Cekani po V sync
 323                if v_period_mx = '1' then
 324                   vcnt_reset <= '1';
 325                   req_en(1) <= '1';
 326                   out_en(1) <= '1';
 327                   vfsm_nst <= vstDraw;
 328                else
 329                   vfsm_nst <= vstWaitPeriod;
 330                end if;
 331        end case;
 332     end process;
 333  
 334     -- Comparators
 335     req_delay_mx   <= use_rqdelay when hcnt(2 downto 0) = conv_std_logic_vector(REQ_DELAY-1, 3) else '0';
 336     h_pixels_mx    <= '1' when hcnt(11 downto 0) = h_pixels else '0';
 337     v_lines_mx     <= '1' when vcnt(11 downto 0) = v_lines else '0';
 338     h_syncstart_mx <= '1' when hcnt(6 downto 0)  = h_syncstart else '0';
 339     h_syncend_mx   <= '1' when hcnt(6 downto 0)  = h_syncend else '0';
 340     h_period_mx    <= '1' when hcnt(6 downto 0)  = h_period else '0';
 341     v_syncstart_mx <= '1' when vcnt(5 downto 0)  = v_syncstart else '0';
 342     v_syncend_mx   <= '1' when vcnt(3 downto 0)  = v_syncend else '0';
 343     v_period_mx    <= '1' when vcnt(5 downto 0)  = v_period else '0';
 344  
 345     -- Horizontal/vertical counter
 346     hcnt_ctrl: process(CLK, ireset, hcnt_reset)
 347     begin
 348        if (ireset = '1') then
 349           hcnt <= (others => '0');
 350        elsif (CLK'event and CLK = '1') then
 351           if hcnt_reset = '1' then
 352              hcnt <= (others => '0');
 353           else
 354              hcnt <= hcnt + 1;
 355           end if;
 356        end if;
 357     end process;
 358  
 359     vcnt_ctrl: process(CLK, ireset, vcnt_reset, vcnt_en)
 360     begin
 361        if (ireset = '1') then
 362           vcnt <= (others => '0');
 363        elsif (CLK'event and CLK = '1') then
 364           if (vcnt_reset = '1') then
 365              vcnt <= (others => '0');
 366           elsif vcnt_en = '1' then
 367              vcnt <= vcnt + 1;
 368           end if;
 369        end if;
 370     end process;
 371  
 372  end arch_vga_controller;
 373  
Zobrazeno: 679754x Naposledy: 28.6.2022 20:06:40