library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity vgacore is port ( reset: in std_logic; -- reset clock: in std_logic; -- VGA dot clock hsyncb: buffer std_logic; -- horizontal (line) sync vsyncb: out std_logic; -- vertical (frame) sync rgb: out std_logic_vector(5 downto 0); -- red,green,blue colors addr: out std_logic_vector(14 downto 0); -- address to video RAM data: in std_logic_vector(7 downto 0); -- data from video RAM csb: out std_logic; -- video RAM chip enable oeb: out std_logic; -- video RAM output enable web: out std_logic -- video RAM write enable ); end vgacore; architecture vgacore_arch of vgacore is signal hcnt: std_logic_vector(8 downto 0); -- horizontal pixel counter signal vcnt: std_logic_vector(9 downto 0); -- vertical line counter signal pixrg: std_logic_vector(7 downto 0); -- byte register for 4 pixels signal blank: std_logic; -- video blanking signal signal pblank: std_logic; -- pipelined video blanking signal begin A: process(clock,reset) begin -- reset asynchronously clears pixel counter if reset='1' then hcnt <= "000000000"; -- horiz. pixel counter increments on rising edge of dot clock elsif (clock'event and clock='1') then -- horiz. pixel counter rolls-over after 381 pixels if hcnt<380 then hcnt <= hcnt + 1; else hcnt <= "000000000"; end if; end if; end process; B: process(hsyncb,reset) begin -- reset asynchronously clears line counter if reset='1' then vcnt <= "0000000000"; -- vert. line counter increments after every horiz. line elsif (hsyncb'event and hsyncb='1') then -- vert. line counter rolls-over after 528 lines if vcnt<527 then vcnt <= vcnt + 1; else vcnt <= "0000000000"; end if; end if; end process; C: process(clock,reset) begin -- reset asynchronously sets horizontal sync to inactive if reset='1' then hsyncb <= '1'; -- horizontal sync is recomputed on the rising edge of every dot clock elsif (clock'event and clock='1') then -- horiz. sync low in this interval to signal start of new line if (hcnt>=291 and hcnt<337) then hsyncb <= '0'; else hsyncb <= '1'; end if; end if; end process; D: process(hsyncb,reset) begin -- reset asynchronously sets vertical sync to inactive if reset='1' then vsyncb <= '1'; -- vertical sync is recomputed at the end of every line of pixels elsif (hsyncb'event and hsyncb='1') then -- vert. sync low in this interval to signal start of a new frame if (vcnt>=490 and vcnt<492) then vsyncb <= '0'; else vsyncb <= '1'; end if; end if; end process; -- blank video outside of visible region: (0,0) -> (255,479) E: blank <= '1' when (hcnt>=256 or vcnt>=480) else '0'; -- store the blanking signal for use in the next pipeline stage F: process(clock,reset) begin if reset='1' then pblank <= '0'; elsif (clock'event and clock='1') then pblank <= blank; end if; end process; -- video RAM control signals G: csb <= '0'; -- enable the RAM web <= '1'; -- disable writing to the RAM oeb <= blank; -- enable the RAM outputs when video is not blanked -- read 8 bit data located in addr located in vcnt(x) and hcnt(y) H: addr <= vcnt(7 downto 0) & hcnt(6 downto 0); I: process(clock,reset) begin -- clear the pixel register on reset if reset='1' then pixrg <= "00000000"; -- pixel clock controls changes in pixel register elsif (clock'event and clock='1') then if (vcnt <77) then pixrg <= data; -- load 4 pixels from RAM else pixrg <= "00000000"; end if; end if; end process; J: process(clock,reset) begin -- blank the video on reset if reset='1' then rgb <= "000000"; -- update the color outputs on every dot clock elsif (clock'event and clock='1') then -- map the pixel to a color if the video is not blanked if pblank='0' then case pixrg(7 downto 0) is -- each pixel represented by 1 byte when "00000000" => rgb <= "000000"; -- black when "00000001" => rgb <= "000001"; -- dark dark blue when "00000010" => rgb <= "000010"; -- navy blue when "00000011" => rgb <= "000011"; -- blue when "00000100" => rgb <= "000100"; -- dark green when "00000101" => rgb <= "000101"; -- forrest green when "00000110" => rgb <= "000110"; -- blue green tint when "00000111" => rgb <= "000111"; -- light blue when "00001000" => rgb <= "001000"; -- green when "00001001" => rgb <= "001001"; -- green blue when "00001010" => rgb <= "001010"; -- sea green when "00001011" => rgb <= "001011"; -- sky blue when "00001100" => rgb <= "001100"; -- bright green when "00001101" => rgb <= "001101"; -- darker bright green when "00001110" => rgb <= "001110"; -- lime green when "00001111" => rgb <= "001111"; -- lightest blue when "00010000" => rgb <= "010000"; -- dark brown when "00010001" => rgb <= "010001"; -- light brown when "00010010" => rgb <= "010010"; -- dark purple when "00010011" => rgb <= "010011"; -- purple when "00010100" => rgb <= "010100"; -- purple blue when "00010101" => rgb <= "010101"; -- ugly green when "00010110" => rgb <= "010110"; -- dark grey when "00010111" => rgb <= "010111"; -- grey blue when "00011000" => rgb <= "011000"; -- blue grey when "00011001" => rgb <= "011001"; -- light ugly green when "00011010" => rgb <= "011010"; -- lighter ugly green when "00011011" => rgb <= "011011"; -- bluer ugly green when "00011100" => rgb <= "011100"; -- bluer when "00011101" => rgb <= "011101"; -- light green when "00011110" => rgb <= "011110"; -- lighter green when "00011111" => rgb <= "011111"; -- green when "00100000" => rgb <= "100000"; -- light blue when "00100001" => rgb <= "100001"; -- brown orange when "00100010" => rgb <= "100010"; -- brown purple when "00100011" => rgb <= "100011"; when "00100100" => rgb <= "100100"; when "00100101" => rgb <= "100101"; when "00100110" => rgb <= "100110"; when "00100111" => rgb <= "100111"; when "00101000" => rgb <= "101000"; when "00101001" => rgb <= "101001"; when "00101010" => rgb <= "101010"; when "00101011" => rgb <= "101011"; when "00101100" => rgb <= "101100"; when "00101101" => rgb <= "101101"; when "00101110" => rgb <= "101110"; when "00101111" => rgb <= "101111"; when "00110000" => rgb <= "110000"; when "00110001" => rgb <= "110001"; when "00110010" => rgb <= "110010"; when "00110011" => rgb <= "110011"; when "00110100" => rgb <= "110100"; when "00110101" => rgb <= "110101"; when "00110110" => rgb <= "110110"; when "00110111" => rgb <= "110111"; when "00111000" => rgb <= "111000"; when "00111001" => rgb <= "111001"; when "00111010" => rgb <= "111010"; when "00111011" => rgb <= "111011"; when "00111100" => rgb <= "111100"; -- yellow when "00111101" => rgb <= "111101"; -- yellow when "00111110" => rgb <= "111110"; -- yellow when "11111111" => rgb <= "111111"; when others => rgb <= "111111"; -- white end case; -- otherwise, output black if the video is blanked else rgb <= "000000"; -- black end if; end if; end process; end vgacore_arch;