-------------------------------------------------------------------------------
-- Title      : NASCOM 2 video generator for VGA monitors
-- Project    : 
-------------------------------------------------------------------------------
-- File       : video.vhd
-- Author     : U-MATTHIAS-THINKP\Matthias  <Matthias@matthias-thinkp>
-- Company    : 
-- Created    : 2009-01-03
-- Last update: 2009-01-03
-- Platform   : 
-- Standard   : VHDL'93
-------------------------------------------------------------------------------
-- Description: 
-------------------------------------------------------------------------------
-- Copyright (c) 2009 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2009-01-03  1.0      Matthias	Created
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity video is
  
  port (
    CLK              : in  std_logic;   -- Should be 25.175 MHz
    DATA_I           : in  std_logic_vector(7 downto 0);  -- Data from video ram
    ADDR_O           : out std_logic_vector(9 downto 0);  -- Addr to video ram
    RED, GREEN, BLUE : out std_logic_vector(3 downto 0);  -- VGA output to DAC
    VSYNC, HSYNC     : out std_logic);  -- VGA sync output

end video;

architecture Behavioral of video is
  component syncgen
    port (
      CLKPIXEL : in  STD_LOGIC;
      VSYNC    : out STD_LOGIC;
      HSYNC    : out STD_LOGIC;
      COLUMN   : out STD_LOGIC_VECTOR (9 downto 0);
      ROW      : out STD_LOGIC_VECTOR (9 downto 0));
  end component;

  component videogen
    port (
      ROW              : in  STD_LOGIC_VECTOR (9 downto 0);
      COLUMN           : in  STD_LOGIC_VECTOR (9 downto 0);
      CLK              : in  STD_LOGIC;
      RED, GREEN, BLUE : out STD_LOGIC_VECTOR(3 downto 0);
      VRAM_ADDR_O      : out STD_LOGIC_VECTOR(9 downto 0);
      VRAM_DATA_I      : in  STD_LOGIC_VECTOR(7 downto 0));
  end component;
attribute iob : string;                 -- pull flip-flop into IOB  
signal vsync_int, hsync_int : std_logic := '1';  -- vga sync from syncgen
signal column, row : std_logic_vector(9 downto 0);  -- screen position from syncgen
signal red_out, green_out, blue_out : std_logic_vector(3 downto 0);
signal vram_addr_out : std_logic_vector(9 downto 0);
signal vsync_d1, vsync_d2, vsync_d3, vsync_d4, hsync_d1, hsync_d2, hsync_d3, hsync_d4 : std_logic := '1';  -- delay sync signals by videogen latency

attribute iob of VSYNC, HSYNC : signal is "TRUE";
attribute iob of RED, GREEN, BLUE : signal is "TRUE";
begin  -- Behavioral

syncgen_inst : syncgen port map (
  CLKPIXEL => CLK,
  VSYNC    => vsync_int,
  HSYNC    => hsync_int,
  COLUMN   => column,
  ROW      => row);
  
videogen_inst : videogen port map (
  ROW         => row,
  COLUMN      => column,
  CLK         => CLK,
  RED         => red_out,
  GREEN       => green_out,
  BLUE        => blue_out,
  VRAM_ADDR_O => vram_addr_out,
  VRAM_DATA_I => DATA_I);

ADDR_O <= vram_addr_out;

-- purpose: output register for video data
-- type   : sequential
-- inputs : CLK, red_out, blue_out, green_out
-- outputs: RED, BLUE, GREEN
viddataff: process (CLK)
begin  -- process viddataff
 if rising_edge(CLK) then    -- rising clock edge
    RED <= red_out;
    GREEN <= green_out;
    BLUE <= blue_out;
  end if;
end process viddataff;

-- purpose: delay sync signals by 3+1 cycles
-- type   : sequential
-- inputs : CLK, vsync_int, hsync_int
-- outputs: VSYNC, HSYNC
syncdelay: process (CLK)
begin  -- process
  if rising_edge(CLK) then
    vsync_d1 <= vsync_int;
    vsync_d2 <= vsync_d1;
    vsync_d3 <= vsync_d2;
    vsync_d4 <= vsync_d3;
    VSYNC <= vsync_d4;

    hsync_d1 <= hsync_int;
    hsync_d2 <= hsync_d1;
    hsync_d3 <= hsync_d2;
    hsync_d4 <= hsync_d3;
    HSYNC <= hsync_d4;
  end if;
end process;

end Behavioral;
