Files
VGA/src/VGA_test.vhd
Max P a73f125357 Refactors VGA timing and mode handling
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.
2025-04-26 10:26:52 +00:00

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;