------------------------------------------------------------------------------- -- th9958_vga_upcon.vhd -- VGA upconverter -- -- Copyright (C) 2008 Takayuki Hara -- All rights reserved. ------------------------------------------------------------------------------- -- -- Redistribution and use of this software or any derivative works, -- are permitted provided that the following conditions are met: -- -- 1. Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- 2. Redistributions in binary form must reproduce the above -- copyright notice, this list of conditions and the following -- disclaimer in the documentation and/or other materials -- provided with the distribution. -- 3. Redistributions may not be sold, nor may they be used in a -- commercial product or activity without specific prior written -- permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- ------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE WORK.TH9958_CONFIG.ALL; ENTITY TH9958_VGA_UPCON IS PORT( CLK : IN STD_LOGIC; RESET_N : IN STD_LOGIC; ENABLE : IN STD_LOGIC; H_CNT : IN STD_LOGIC_VECTOR( 9 DOWNTO 0 ); V_CNT : IN STD_LOGIC_VECTOR( 9 DOWNTO 0 ); RIGHT_SIDE : IN STD_LOGIC; R : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 ); G : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 ); B : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 ); VGA_R : OUT STD_LOGIC_VECTOR( 5 DOWNTO 0 ); VGA_G : OUT STD_LOGIC_VECTOR( 5 DOWNTO 0 ); VGA_B : OUT STD_LOGIC_VECTOR( 5 DOWNTO 0 ); VGA_HS_N : OUT STD_LOGIC; VGA_VS_N : OUT STD_LOGIC ); END TH9958_VGA_UPCON; ARCHITECTURE RTL OF TH9958_VGA_UPCON IS COMPONENT TH9958_LINEBUF_RAM PORT ( CLK : IN STD_LOGIC; RAM_A : IN STD_LOGIC_VECTOR( 9 DOWNTO 0 ); RAM_WE : IN STD_LOGIC; RAM_DR : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 ); RAM_DG : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 ); RAM_DB : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 ); RAM_QR : OUT STD_LOGIC_VECTOR( 5 DOWNTO 0 ); RAM_QG : OUT STD_LOGIC_VECTOR( 5 DOWNTO 0 ); RAM_QB : OUT STD_LOGIC_VECTOR( 5 DOWNTO 0 ) ); END COMPONENT; SIGNAL FF_VALID_X : STD_LOGIC; SIGNAL FF_WRT_BUF : STD_LOGIC; SIGNAL W_RAM_AR : STD_LOGIC_VECTOR( 9 DOWNTO 0 ); SIGNAL W_RAM_AW : STD_LOGIC_VECTOR( 9 DOWNTO 0 ); SIGNAL W_RAM_A1 : STD_LOGIC_VECTOR( 9 DOWNTO 0 ); SIGNAL W_RAM_A2 : STD_LOGIC_VECTOR( 9 DOWNTO 0 ); SIGNAL W_RAM_WE1 : STD_LOGIC; SIGNAL W_RAM_WE2 : STD_LOGIC; SIGNAL W_RAM_QR1 : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_RAM_QG1 : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_RAM_QB1 : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_RAM_QR2 : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_RAM_QG2 : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_RAM_QB2 : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_RAM_QR : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_RAM_QG : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_RAM_QB : STD_LOGIC_VECTOR( 5 DOWNTO 0 ); SIGNAL W_H_CNT_OFF : STD_LOGIC_VECTOR( 10 DOWNTO 0 ); BEGIN VGA_R <= W_RAM_QR WHEN( FF_VALID_X = '1' )ELSE (OTHERS => '0'); VGA_G <= W_RAM_QG WHEN( FF_VALID_X = '1' )ELSE (OTHERS => '0'); VGA_B <= W_RAM_QB WHEN( FF_VALID_X = '1' )ELSE (OTHERS => '0'); --------------------------------------------------------------------------- -- DUAL LINE BUFFER --------------------------------------------------------------------------- U_1ST_LINE: TH9958_LINEBUF_RAM PORT MAP ( CLK => CLK , RAM_A => W_RAM_A1 , RAM_WE => W_RAM_WE1 , RAM_DR => R , RAM_DG => G , RAM_DB => B , RAM_QR => W_RAM_QR1 , RAM_QG => W_RAM_QG1 , RAM_QB => W_RAM_QB1 ); U_2ND_LINE: TH9958_LINEBUF_RAM PORT MAP ( CLK => CLK , RAM_A => W_RAM_A2 , RAM_WE => W_RAM_WE2 , RAM_DR => R , RAM_DG => G , RAM_DB => B , RAM_QR => W_RAM_QR2 , RAM_QG => W_RAM_QG2 , RAM_QB => W_RAM_QB2 ); --------------------------------------------------------------------------- W_H_CNT_OFF <= ('0' & H_CNT) + 684; W_RAM_AR <= H_CNT; W_RAM_AW <= ('0' & H_CNT( 9 DOWNTO 1 )) WHEN( RIGHT_SIDE = '0' )ELSE W_H_CNT_OFF( 10 DOWNTO 1 ); W_RAM_A1 <= W_RAM_AW WHEN( FF_WRT_BUF = '0' )ELSE W_RAM_AR; W_RAM_WE1 <= NOT FF_WRT_BUF; W_RAM_A2 <= W_RAM_AW WHEN( FF_WRT_BUF = '1' )ELSE W_RAM_AR; W_RAM_WE2 <= FF_WRT_BUF; W_RAM_QR <= W_RAM_QR1 WHEN( FF_WRT_BUF = '1' )ELSE W_RAM_QR2; W_RAM_QG <= W_RAM_QG1 WHEN( FF_WRT_BUF = '1' )ELSE W_RAM_QG2; W_RAM_QB <= W_RAM_QB1 WHEN( FF_WRT_BUF = '1' )ELSE W_RAM_QB2; --------------------------------------------------------------------------- PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_WRT_BUF <= '0'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( H_CNT = 0 AND RIGHT_SIDE = '0' )THEN FF_WRT_BUF <= NOT FF_WRT_BUF; END IF; END IF; END IF; END PROCESS; --------------------------------------------------------------------------- -- TIMING --------------------------------------------------------------------------- PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN VGA_HS_N <= '1'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( H_CNT = C_HS_SX )THEN VGA_HS_N <= '0'; ELSIF( H_CNT = C_HS_EX )THEN VGA_HS_N <= '1'; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN VGA_VS_N <= '1'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( V_CNT = 0 )THEN VGA_VS_N <= '0'; ELSIF( V_CNT = 1 )THEN VGA_VS_N <= '1'; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_VALID_X <= '1'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( H_CNT = 120 )THEN FF_VALID_X <= '1'; ELSIF( H_CNT = (120 + (30 + 512 + 20)) )THEN FF_VALID_X <= '0'; END IF; END IF; END IF; END PROCESS; END RTL;