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

Subversion Repositories lq057q3dc02

[/] [lq057q3dc02/] [trunk/] [design/] [vsyncx_control.vhd] - Rev 47

Compare with Previous | Blame | View Log

------------------------------------------------------------------------------
-- Copyright (C) 2007 Jonathon W. Donaldson
--                    jwdonal a t opencores DOT org
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation; either version 2 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program; if not, write to the Free Software
--  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--
------------------------------------------------------------------------------
--
-- $Id: vsyncx_control.vhd,v 1.1 2008-11-07 00:48:12 jwdonal Exp $
--
-- Description:
--  This file controls VSYNCx.  VSYNCx is dependent upon the number of HSYNCx
--  activations (i.e. the numbers of lines) that have passed.  The really cool
--  thing about the VSYNCx control state machine is that it is _EXACTLY_ the
--  same as the HSYNCx control state machine expect that instead of have the
--  counter process counting CLK_LCD cycles we have counting HSYNCx cycles!
--  It's really that simple!
--
--  VSYNCx signifies the start of a frame.  HSYNCx must pulse exactly 7 times
--  (i.e. 7 lines) after (minimum of 0 ns after - TVh) VSYNCx pulse occurs
--  before sending data to the LCD.  You can consider these 7 lines as blank
--  lines that "live" above the physical top of the screen.  After 7 HSYNCx
--  pulses have passed we can then start with line 1 and go to line 240 for a
--  total of 7 + 240 lines = 247 lines (or HSYNCx pulses) for every complete
--  image or "frame" drawn to the screen!
--
-- Note: Even though VSYNCx controls the start of a frame you cannot simply
-- disable HSYNCx cycling once the data has been shifted into the LCD.  This
-- is b/c there is a MAX cycle time spec in the datasheet of 450 clocks!
-- It is simplest to just leave HSYNCx running at all times no matter what.
--
-- Structure:
--   - xupv2p.ucf
--   - components.vhd
--   - lq057q3dc02_tb.vhd
--   - lq057q3dc02.vhd
--     - dcm_sys_to_lcd.xaw
--     - video_controller.vhd
--       - enab_control.vhd
--       - hsyncx_control.vhd
--       - vsyncx_control.vhd
--       - clk_lcd_cyc_cntr.vhd
--     - image_gen_bram.vhd
--       - image_gen_bram_red.xco
--       - image_gen_bram_green.xco
--       - image_gen_bram_blue.xco
--
------------------------------------------------------------------------------
--
-- Naming Conventions:
--   active low signals                                       "*x"
--   clock signal                                             "CLK_*"
--   reset signal                                             "RST"
--   generic/constant                                         "C_*"
--   user defined type                                        "TYPE_*"
--   state machine next state                                 "*_ns"
--   state machine current state                              "*_cs""
--   pipelined signals                                        "*_d#"
--   register delay signals                                   "*_p#"
--   signal                                                   "*_sig"
--   variable                                                 "*_var"
--   storage register                                         "*_reg"
--   clock enable signals                                     "*_ce"
--   internal version of output port used as connecting wire  "*_wire"
--   input/output port                                        "ALL_CAPS"
--   process                                                  "*_PROC"
--
------------------------------------------------------------------------------
 
--////////////////////--
-- LIBRARY INCLUSIONS --
--////////////////////--
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
 
--////////////////////--
-- ENTITY DECLARATION --
--////////////////////--
ENTITY vsyncx_control IS
 
  -----------------------------------------------------------------
  -- Generic Descriptions:
  --
  -- C_LINE_NUM_WIDTH   -- Must be at least 9 bits to hold maximum
  --                    -- timespec of 280 lines.
  -----------------------------------------------------------------
  generic (
 
    C_VSYNC_TV,
    C_VSYNC_TVP,
    C_LINE_NUM_WIDTH : POSITIVE
 
  );
 
  port (
 
    RSTx,
    CLK_LCD,
    HSYNCx : IN STD_LOGIC;
 
    LINE_NUM : OUT STD_LOGIC_VECTOR(C_LINE_NUM_WIDTH-1 downto 0);
 
    VSYNCx : OUT STD_LOGIC
 
  );
 
END ENTITY vsyncx_control;
 
--////////////////////////--
-- ARCHITECTURE OF ENTITY --
--////////////////////////--
ARCHITECTURE vsyncx_control_arch OF vsyncx_control IS
 
  --Enables/Disables the line counter process
  signal line_cnt_en_sig : std_logic;
 
  --Stores current line number.
  --This register is attached to the LINE_NUM output.
  signal line_num_reg : std_logic_vector(C_LINE_NUM_WIDTH-1 downto 0) := (others => '0');
 
  ---------------------------------------------------------------
  -- States for VSYNCx_Line_Cntr_*_PROC
  ---------------------------------------------------------------
  --FRAME_START => Start of a new frame
  --ADD => Add one (1) to the line count
  --ADD_WAIT => Wait for HSYNCx pulse to pass
  --READY => Get ready to add one (1) for the next line
  type TYPE_Line_Cntr_Sts is ( FRAME_START, ADD, ADD_WAIT, READY );
  signal Line_Cntr_cs : TYPE_Line_Cntr_Sts;
  signal Line_Cntr_ns : TYPE_Line_Cntr_Sts;
 
begin
 
  --///////////////////////--
  -- CONCURRENT STATEMENTS --
  --///////////////////////--
  LINE_NUM <= line_num_reg;
 
 
  --///////////--
  -- PROCESSES --
  --///////////--
 
  ------------------------------------------------------------------
  --  Process Description:
  --    This is finite state machine process 1 of 3 for the VSYNCx
  --    signal controller.  This process only controls the reset of
  --    the state and the "current state to next state" assignment.
  --  
  --  Inputs:
  --    RSTx
  --    CLK_LCD
  --  
  --  Outputs:
  --    Line_Cntr_cs
  --
  --  Notes:
  --    N/A
  ------------------------------------------------------------------
  VSYNCx_Line_Cntr_1_PROC : process( RSTx, CLK_LCD )
  begin
 
    if( RSTx = '0' ) then
 
      Line_Cntr_cs <= READY;
 
    elsif( CLK_LCD'event and CLK_LCD = '1' ) then
 
      Line_Cntr_cs <= Line_Cntr_ns;
 
    end if;
 
  end process VSYNCx_Line_Cntr_1_PROC;
 
 
  ------------------------------------------------------------------
  --  Process Description:
  --    This is finite state machine process 2 of 3 for the VSYNCx
  --    signal controller.  This process controls all of the state
  --    changes.
  --  
  --  Inputs:
  --    Line_Cntr_cs
  --    HSYNCx
  --    line_num_reg
  --  
  --  Outputs:
  --    Line_Cntr_ns
  --
  --  Notes:
  --    We only want to start counting lines at the first HSYNCx pulse
  --    we see _after_ VSYNCx has been activated.  This is because
  --    VSYNCx must occur before HSYNCx can be counted (NOTE: there is
  --    no sense in couting lines unless we know that a new frame has
  --    started - this is _most_ important for the ENAB_Cntrl process!)
  ------------------------------------------------------------------
  VSYNCx_Line_Cntr_2_PROC : process( Line_Cntr_cs, HSYNCx, line_num_reg )
  begin
 
    case Line_Cntr_cs is
 
      when FRAME_START =>  --reset the counter because we have started a new frame!
 
        if( HSYNCx = '0' ) then -- a new frame is starting (controlled by VSYNCx_control state machine) and here is our first line!
 
          Line_Cntr_ns <= ADD_WAIT; -- do not add +1 lines until HSYNCx goes high!  The rising edge is what counts as a line, not the falling edge!
 
        else
 
          Line_Cntr_ns <= FRAME_START; -- keep waiting for first line to occur after start of new frame
 
        end if;
 
      when ADD_WAIT =>
 
        if( HSYNCx = '1' ) then
 
          Line_Cntr_ns <= ADD;  -- line_num_reg + 1 !
 
        else
 
          Line_Cntr_ns <= ADD_WAIT; -- stay here until HSYNCx has been released b/c we only want to count the rising edge of HSYNCx as a line!
 
        end if;
 
      when ADD =>
 
        Line_Cntr_ns <= READY;  -- get ready to count another line if necessary
 
      when READY =>
 
        if( line_num_reg = C_VSYNC_TV - 1 ) then -- 0 to 254 = 255 lines (first make sure we haven't reach the end of the VSYNC cycle - which is just a little bit longer than the actual number of lines on the screen - TV)
 
          Line_Cntr_ns <= FRAME_START; -- if we've reached the max VSYNC cycle time (i.e. TV) then start over!
 
        elsif( HSYNCx = '0' ) then
 
          Line_Cntr_ns <= ADD_WAIT; -- a new line has started!  line_num_reg + 1!!
 
        else
 
          Line_Cntr_ns <= READY; -- stay here until HSYNCx pulse occurs
 
        end if;
 
      when others => --UH OH!  How did we get here???
 
        Line_Cntr_ns <= FRAME_START;
 
    end case;
 
  end process VSYNCx_Line_Cntr_2_PROC;
 
 
  ------------------------------------------------------------------
  --  Process Description:
  --    This is finite state machine process 3 of 3 for the VSYNCx
  --    signal controller.  This process only controls the change of
  --    of output values based on the current state.
  --  
  --  Inputs:
  --    Line_Cntr_cs
  --  
  --  Outputs:
  --    line_cnt_en_sig
  --
  --  Notes:
  --    N/A
  ------------------------------------------------------------------
  VSYNCx_Line_Cntr_3_PROC : process( Line_Cntr_cs )
  begin
 
    case Line_Cntr_cs is
 
      when FRAME_START => --reset line_num_reg at start of new frame
 
        line_cnt_en_sig <= '0';
 
      when READY =>
 
        line_cnt_en_sig <= '0';
 
      when ADD_WAIT =>
 
        line_cnt_en_sig <= '0';
 
      when ADD => --we will only ever be in this state for one CLK_LCD cycle.  This is IMPORTANT! b/c we only want to count one CLK_LCD cycle worth of the HSYNCx active pulse no matter how long the HSYNCx pulse is!
 
        line_cnt_en_sig <= '1';
 
      when others => --UH OH!  How did we get here???
 
        line_cnt_en_sig <= '0';
 
    end case;
 
  end process VSYNCx_Line_Cntr_3_PROC;
 
 
  ------------------------------------------------------------------
  --  Process Description:
  --    This process starts, stops, and resets the line counter
  --    based on the line count enable signal and the current state
  --    of the line counter state machine.
  --  
  --  Inputs:
  --    RSTx
  --    CLK_LCD
  --  
  --  Outputs:
  --    line_num_reg
  --
  --  Notes:
  --    N/A
  ------------------------------------------------------------------
  Line_cntr_PROC : process( RSTx, CLK_LCD )
  begin
  if( RSTx = '0' ) then
 
    line_num_reg <= (others => '0');
 
  elsif( CLK_LCD'event and CLK_LCD = '1' ) then
 
    if( line_cnt_en_sig = '1' ) then
 
      line_num_reg <= line_num_reg + 1;
 
    elsif( Line_Cntr_cs = FRAME_START ) then
 
      line_num_reg <= (others => '0');
 
    else
 
      line_num_reg <= line_num_reg;
 
    end if;
 
  end if;
 
  end process Line_cntr_PROC;
 
 
  ------------------------------------------------------------------
  --  Process Description:
  --    This process activates/deactivates the VSYNCx signal depending
  --    on the current line number relative to the VSYNC pulse width
  --    paramter.
  --  
  --  Inputs:
  --    RSTx
  --    CLK_LCD
  --  
  --  Outputs:
  --    VSYNCx
  --
  --  Notes:
  --    N/A
  ------------------------------------------------------------------
  VSYNCx_cntrl_PROC : process( RSTx, CLK_LCD )
  begin
 
    if( RSTx = '0' ) then
 
      VSYNCx <= '1';  --INACTIVE
 
    elsif( CLK_LCD'event and CLK_LCD = '1' ) then
 
      if( line_num_reg < C_VSYNC_TVP ) then
 
        VSYNCx <= '0'; --ACTIVE
 
      else
 
        VSYNCx <= '1'; --INACTIVE
 
      end if;
 
    end if;
 
  end process VSYNCx_cntrl_PROC;
 
 
END ARCHITECTURE vsyncx_control_arch;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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