Renames and restructures VGA timing generator for clarity and modularity. Introduces VGA modes package for centralized resolution and timing configuration. Updates related testbenches and constraints to align with new structure. Improves maintainability and flexibility for future VGA mode additions.
216 lines
8.9 KiB
VHDL
216 lines
8.9 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use ieee.math_real.all;
|
|
use work.VGA_Modes_Pkg.all;
|
|
library UNISIM;
|
|
use UNISIM.vcomponents.all;
|
|
|
|
|
|
entity VGA_test is
|
|
generic (
|
|
--@ VGA Mode (0-9) from VGA_Modes_Pkg
|
|
G_VGA_Mode : integer := 2
|
|
);
|
|
port (
|
|
--@ Clock signal; **Rising edge** triggered
|
|
I_CLK : in std_logic;
|
|
--@ @virtualbus VGA-Signals @dir out VGA signals
|
|
--@ Horizontal Sync signal; **Active low**
|
|
O_VGA_HSync : out std_logic;
|
|
--@ Vertical Sync signal; **Active low**
|
|
O_VGA_VSync : out std_logic;
|
|
--@ VGA Pixel Data: 3 bits Red, 3 bits Green, 2 bits Blue
|
|
O_VGA_Pixel : out std_logic_vector(7 downto 0);
|
|
--@ @end
|
|
O_LED : out std_logic := '0'
|
|
);
|
|
end entity VGA_test;
|
|
|
|
architecture RTL of VGA_test is
|
|
|
|
function rgb_to_vector(red : unsigned(2 downto 0); green : unsigned(2 downto 0); blue : unsigned(1 downto 0)) return std_logic_vector is
|
|
begin
|
|
return std_logic_vector(std_logic_vector(red) & std_logic_vector(green) & std_logic_vector(blue));
|
|
end function;
|
|
|
|
signal S_CLK_FB : std_logic;
|
|
signal S_CLK : std_logic;
|
|
|
|
signal I_VGA_PixelCE : std_logic := '0';
|
|
signal I_VGA_PixelRST : std_logic := '1';
|
|
|
|
signal O_VGA_Req_Y_Valid : std_logic;
|
|
signal I_VGA_Req_Y_Ready : std_logic := '0';
|
|
signal O_VGA_Req_Y : std_logic_vector(K_VGA_Modes(G_VGA_Mode).Y_Width-1 downto 0);
|
|
|
|
signal O_VGA_Req_X_Valid : std_logic;
|
|
signal I_VGA_Req_X_Ready : std_logic;
|
|
signal O_VGA_Req_X : std_logic_vector(K_VGA_Modes(G_VGA_Mode).X_Width-1 downto 0);
|
|
|
|
|
|
signal I_VGA_CE : std_logic := '1';
|
|
signal I_VGA_RST : std_logic := '0';
|
|
|
|
signal I_VGA_PixelData_Valid : std_logic;
|
|
signal O_VGA_PixelData_Ready : std_logic;
|
|
signal I_VGA_PixelData : std_logic_vector(7 downto 0);
|
|
|
|
----
|
|
constant K_COLOR_BLACK : std_logic_vector(7 downto 0) := rgb_to_vector("000", "000", "00");
|
|
constant K_COLOR_WHITE : std_logic_vector(7 downto 0) := rgb_to_vector("111", "111", "11");
|
|
|
|
constant K_COLOR_RED : std_logic_vector(7 downto 0) := rgb_to_vector("111", "000", "00");
|
|
constant K_COLOR_GREEN : std_logic_vector(7 downto 0) := rgb_to_vector("000", "111", "00");
|
|
constant K_COLOR_BLUE : std_logic_vector(7 downto 0) := rgb_to_vector("000", "000", "11");
|
|
|
|
constant K_COLOR_CYAN : std_logic_vector(7 downto 0) := rgb_to_vector("000", "111", "11"); -- G + B
|
|
constant K_COLOR_MAGENTA : std_logic_vector(7 downto 0) := rgb_to_vector("111", "000", "11"); -- R + B
|
|
constant K_COLOR_YELLOW : std_logic_vector(7 downto 0) := rgb_to_vector("111", "111", "00"); -- R + G
|
|
|
|
constant K_COLOR_GRAY : std_logic_vector(7 downto 0) := rgb_to_vector("100", "100", "10"); -- mittelgrau
|
|
constant K_COLOR_DARK_GRAY : std_logic_vector(7 downto 0) := rgb_to_vector("010", "010", "01");
|
|
constant K_COLOR_LIGHT_GRAY : std_logic_vector(7 downto 0) := rgb_to_vector("110", "110", "10");
|
|
|
|
constant K_COLOR_ORANGE : std_logic_vector(7 downto 0) := rgb_to_vector("111", "011", "00");
|
|
constant K_COLOR_PINK : std_logic_vector(7 downto 0) := rgb_to_vector("111", "100", "10");
|
|
constant K_COLOR_BROWN : std_logic_vector(7 downto 0) := rgb_to_vector("100", "010", "00");
|
|
constant K_COLOR_LIME : std_logic_vector(7 downto 0) := rgb_to_vector("010", "111", "00");
|
|
constant K_COLOR_NAVY : std_logic_vector(7 downto 0) := rgb_to_vector("000", "000", "01");
|
|
|
|
|
|
constant K_DEFAULT_COLOR : std_logic_vector(7 downto 0) := K_COLOR_CYAN;
|
|
|
|
signal R_CurrentColor : std_logic_vector(7 downto 0);
|
|
signal R_CurrentColorAlt : std_logic_vector(7 downto 0);
|
|
signal R_MUX_Color : std_logic := '0';
|
|
constant K_COLOR_CHANGE_INTERVAL : integer := 16;
|
|
|
|
-- Farbwechsel-Logik (einfache zyklische Farben)
|
|
function next_color(currentColor : std_logic_vector(7 downto 0)) return std_logic_vector is
|
|
begin
|
|
case currentColor is
|
|
when K_COLOR_BLACK => return K_COLOR_WHITE;
|
|
when K_COLOR_WHITE => return K_COLOR_RED;
|
|
when K_COLOR_RED => return K_COLOR_GREEN;
|
|
when K_COLOR_GREEN => return K_COLOR_BLUE;
|
|
when K_COLOR_BLUE => return K_COLOR_CYAN;
|
|
when K_COLOR_CYAN => return K_COLOR_MAGENTA;
|
|
when K_COLOR_MAGENTA => return K_COLOR_YELLOW;
|
|
when K_COLOR_YELLOW => return K_COLOR_GRAY;
|
|
when K_COLOR_GRAY => return K_COLOR_DARK_GRAY;
|
|
when K_COLOR_DARK_GRAY => return K_COLOR_LIGHT_GRAY;
|
|
when K_COLOR_LIGHT_GRAY => return K_COLOR_ORANGE;
|
|
when K_COLOR_ORANGE => return K_COLOR_PINK;
|
|
when K_COLOR_PINK => return K_COLOR_BROWN;
|
|
when K_COLOR_BROWN => return K_COLOR_LIME;
|
|
when K_COLOR_LIME => return K_COLOR_NAVY;
|
|
when K_COLOR_NAVY => return K_COLOR_BLACK; -- wieder von vorn
|
|
when others => return K_DEFAULT_COLOR;
|
|
end case;
|
|
end function;
|
|
|
|
signal R_Error : std_logic_vector(7 downto 0) := (others => '0');
|
|
|
|
signal R_ResetCounter : integer := 0;
|
|
constant K_ResetCounterMax : integer := 255;
|
|
begin
|
|
|
|
INST_ClockManager : DCM_SP
|
|
generic map(
|
|
CLKDV_DIVIDE => 2.0,
|
|
CLKFX_MULTIPLY => 5,
|
|
CLKFX_DIVIDE => 5,
|
|
CLKIN_DIVIDE_BY_2 => false,
|
|
CLKIN_PERIOD => 20.0,
|
|
CLKOUT_PHASE_SHIFT => "NONE",
|
|
CLK_FEEDBACK => "1X",
|
|
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
|
|
DFS_FREQUENCY_MODE => "LOW",
|
|
DLL_FREQUENCY_MODE => "LOW",
|
|
DUTY_CYCLE_CORRECTION => true,
|
|
FACTORY_JF => X"C080",
|
|
PHASE_SHIFT => 0,
|
|
STARTUP_WAIT => false)
|
|
port map
|
|
(
|
|
CLK0 => S_CLK_FB,
|
|
CLKFX => S_CLK,
|
|
CLKFB => S_CLK_FB,
|
|
CLKIN => I_CLK
|
|
);
|
|
|
|
process (I_CLK)
|
|
begin
|
|
if rising_edge(I_CLK) then
|
|
I_VGA_PixelCE <= not I_VGA_PixelCE;
|
|
end if;
|
|
end process;
|
|
|
|
I_VGA_PixelData_Valid <= O_VGA_Req_X_Valid;
|
|
I_VGA_Req_X_Ready <= O_VGA_PixelData_Ready;
|
|
|
|
I_VGA_PixelData <= R_CurrentColor when R_MUX_Color = '0' else
|
|
R_CurrentColorAlt;
|
|
process(S_CLK)
|
|
begin
|
|
if rising_edge(S_CLK) then
|
|
if R_ResetCounter = K_ResetCounterMax then
|
|
I_VGA_PixelRST <= '0';
|
|
|
|
if O_VGA_Req_X_Valid = '1' and O_VGA_PixelData_Ready = '1' then
|
|
if unsigned(O_VGA_Req_X) = to_unsigned(K_VGA_Modes(G_VGA_Mode).X_Resolution-1, O_VGA_Req_X'length) then
|
|
R_MUX_Color <= '0';
|
|
elsif unsigned(O_VGA_Req_X) = to_unsigned((K_VGA_Modes(G_VGA_Mode).X_Resolution/2)-1, O_VGA_Req_X'length) then
|
|
R_MUX_Color <= '1';
|
|
end if;
|
|
end if;
|
|
|
|
if O_VGA_Req_Y_Valid = '1' and I_VGA_Req_Y_Ready = '0' then
|
|
I_VGA_Req_Y_Ready <= '1';
|
|
if O_VGA_Req_Y = (O_VGA_Req_Y'range => '0') then
|
|
R_CurrentColor <= K_DEFAULT_COLOR;
|
|
R_CurrentColorAlt <= next_color(K_DEFAULT_COLOR);
|
|
elsif (unsigned(O_VGA_Req_Y) mod K_COLOR_CHANGE_INTERVAL) = 0 then
|
|
R_CurrentColor <= next_color(R_CurrentColor);
|
|
R_CurrentColorAlt <= next_color(R_CurrentColorAlt);
|
|
end if;
|
|
elsif I_VGA_Req_Y_Ready = '1' then
|
|
I_VGA_Req_Y_Ready <= '0';
|
|
end if;
|
|
else
|
|
R_ResetCounter <= R_ResetCounter + 1;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
INST_VGA : entity work.VGA
|
|
generic map(
|
|
G_VGA_Mode => G_VGA_Mode
|
|
)
|
|
port map(
|
|
I_VGA_PixelCLK => S_CLK,
|
|
I_VGA_PixelCE => I_VGA_PixelCE,
|
|
I_VGA_PixelRST => I_VGA_PixelRST,
|
|
O_VGA_HSync => O_VGA_HSync,
|
|
O_VGA_VSync => O_VGA_VSync,
|
|
O_VGA_Pixel => O_VGA_Pixel,
|
|
I_VGA_CLK => S_CLK,
|
|
I_VGA_CE => I_VGA_CE,
|
|
I_VGA_RST => I_VGA_RST,
|
|
O_VGA_Req_Y_Valid => O_VGA_Req_Y_Valid,
|
|
I_VGA_Req_Y_Ready => I_VGA_Req_Y_Ready,
|
|
O_VGA_Req_Y => O_VGA_Req_Y,
|
|
O_VGA_Req_X_Valid => O_VGA_Req_X_Valid,
|
|
I_VGA_Req_X_Ready => I_VGA_Req_X_Ready,
|
|
O_VGA_Req_X => O_VGA_Req_X,
|
|
I_VGA_PixelData_Valid => I_VGA_PixelData_Valid,
|
|
O_VGA_PixelData_Ready => O_VGA_PixelData_Ready,
|
|
I_VGA_PixelData => I_VGA_PixelData,
|
|
O_VGA_Error => R_Error
|
|
);
|
|
|
|
O_LED <= R_Error(0);
|
|
|
|
end architecture RTL;
|