I would be interested in seeing the VGA/CPLD code you have.
Thanks!
I will post this later today
I've got it doing something like 80x30 Text with colour at 640x480 I think.
Code: Select all
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity vga6502 is
port
(
clk : in std_logic;
sl : out std_logic;
latch : out std_logic;
reset : in std_logic;
ma : out std_logic_vector(11 downto 0);
ra : out std_logic_vector(3 downto 0);
blank : out std_logic;
hsync : out std_logic;
vsync : out std_logic
);
end entity;
architecture behavioral of vga6502 is
signal CLK8: std_logic := '0';
signal CLKDIV: integer range 0 to 3;
signal SRDIV: unsigned (2 downto 0);
constant H_TOT: integer := 100;
constant H_FP: integer := 2;
constant H_BP: integer := 6;
constant H_SW: integer := 12;
signal H_CNTR: integer range 0 to 100;
signal H_END: std_logic := '0';
signal H_BLANK: std_logic := '0';
constant V_TOT: integer := 525;
constant V_FP: integer := 10;
constant V_SW: integer := 2;
constant V_BP: integer := 33;
signal V_CNTR: integer range 0 to 525;
signal V_BLANK: std_logic := '0';
signal CH_CNTR: integer range 0 to 4096;
signal RW_REG: integer range 0 to 4096;
signal CH_CLK: std_logic := '0';
signal SL_CNTR: integer range 0 to 15;
begin
blank <= (V_BLANK OR H_BLANK);
---
--- Clock Divider
--- Divides 25.175 Mhz Pixel clock by 8, i.e to load one character every 8 clocks
---
charclk:
process(clk, reset)
begin
if reset = '1' then
CLKDIV <= 0;
elsif (rising_edge(clk)) then
if (CLKDIV = 3) then
CLK8 <= NOT(CLK8);
CLKDIV <= 0;
else
CLKDIV <= CLKDIV + 1;
end if;
end if;
end process;
--
-- Horizontal
--
H_cnt:
process(clk8, reset)
begin
if (reset = '1') then
H_CNTR <= 0;
elsif rising_edge(clk8) then
if (H_CNTR = (H_TOT - 1)) then
H_END <= '1';
H_CNTR <= 0;
else
H_END <= '0';
H_CNTR <= H_CNTR + 1;
end if;
end if;
end process;
H_display:
process(clk8)
begin
if rising_edge(clk8) then
if (H_CNTR >= (H_SW + H_BP)) AND (H_CNTR < (H_TOT - H_FP)) then
H_BLANK <= '0';
else
H_BLANK <= '1';
end if;
end if;
end process;
H_sync:
process(clk)
begin
if rising_edge(clk) then
if (H_CNTR < H_SW) then
HSYNC <= '0';
else
HSYNC <= '1';
end if;
end if;
end process;
---
--- Vertical
---
V_cnt:
process (H_END, reset)
begin
if (reset = '1') then
V_CNTR <= 0;
elsif falling_edge(H_END) then
if (V_CNTR = (V_TOT-1)) then
V_CNTR <= 0;
else
V_CNTR <= V_CNTR + 1;
end if;
end if;
end process;
V_display:
process(H_END)
begin
if falling_edge(H_END) then
if (V_CNTR >= (V_SW + V_BP)) AND (V_CNTR < (V_TOT - V_FP)) then
V_BLANK <= '0';
else
V_BLANK <= '1';
end if;
end if;
end process;
V_sync:
process(H_END)
begin
if falling_edge(H_END) then
if (V_CNTR < V_SW) then
VSYNC <= '1';
else
VSYNC <= '0';
end if;
end if;
end process;
---
--- Scanline Counter
--- Outputs RA row address to Char Rom
---
SL_cnt:
process(H_END, reset)
begin
if (reset = '1') then
SL_CNTR <= 0;
elsif falling_edge(H_END) then
if (SL_CNTR = 15) or (V_BLANK = '1') then
SL_CNTR <= 0;
else
SL_CNTR <= SL_CNTR + 1;
end if;
end if;
end process;
RA <= std_logic_vector(to_unsigned(SL_CNTR, RA'length));
---
--- Char Row Clock, increment row count every 16 scanlines
---
CHCLK:
process(SL_CNTR)
begin
if (SL_CNTR = 15) then
CH_CLK <= '1';
else
CH_CLK <= '0';
end if;
end process;
RW_cnt:
process(reset,CH_CLK,V_BLANK)
begin
if (reset = '1') OR (V_BLANK = '1') then
RW_REG <= 0;
elsif falling_edge(CH_CLK) then
RW_REG <= RW_REG + 80;
else
RW_REG <= RW_REG;
end if;
end process;
---
--- Char Counter
--- Generates linear memory addresses
---
C_cnt:
process(reset,CLK8)
begin
if (reset = '1') then
CH_CNTR <= 0;
elsif rising_edge(CLK8) then
if (H_CNTR >= (H_SW + H_BP)) AND (H_CNTR < (H_TOT - H_FP)) then
CH_CNTR <= CH_CNTR + 1;
else
CH_CNTR <= RW_REG;
end if;
end if;
end process;
MA <= std_logic_vector(to_unsigned(CH_CNTR, MA'length));
---
--- Shift Register control
--- load the shift register every 8 clocks
---
SR_ctrl:
process(reset,clk)
begin
if reset = '1' then
SRDIV <= (others => '0');
elsif rising_edge(clk) then
if (H_CNTR >= (H_SW + H_BP)) AND (H_CNTR <= (H_TOT - H_FP)) then
SRDIV <= SRDIV + 1;
else
SRDIV <= (others => '0');
end if;
end if;
end process;
--- Load shift register
SL <= '0' when (SRDIV = "0" AND (CLK = '1')) else '1';
--- Load color latch
LATCH <= '1' when (SRDIV = "0" AND (CLK = '1')) else '0';
end behavioral;
