diff --git a/src/VGATimingGenerator_pb.vhd b/src/VGATimingGenerator_pb.vhd index 225e307..e9db739 100644 --- a/src/VGATimingGenerator_pb.vhd +++ b/src/VGATimingGenerator_pb.vhd @@ -1,14 +1,3 @@ ----------------------------------------------------------------------------------- ---@ - Name: **Pipeline Register** ---@ - Version: 0.0.1 ---@ - Author: _Maximilian Passarello ([Blog](mpassarello.de))_ ---@ - License: [MIT](LICENSE) ---@ ---@ The VGA Timing Generator is a simple module that generates the horizontal and vertical sync signals for a VGA display. ---@ ---@ ## History ---@ - 0.0.1 (2024-03-24) Initial version ----------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; @@ -17,18 +6,18 @@ use ieee.math_real.all; entity VGATimingGenerator_pb is port ( --@ Clock signal; **Rising edge** triggered - I_CLK : in std_logic; + I_CLK : in std_logic; --@ Clock Enable signal - I_CE : in std_logic; + I_CE : in std_logic; --@ Synchronous reset signal - I_RST : in std_logic; + I_RST : in std_logic; --@ Ready signal to indicate that the pixel data is ready to be displayed O_PixelReady : out std_logic; --@ @virtualbus VGA-Timing-Signals @dir out VGA timing signals --@ Horizontal Sync signal; **Active low** - O_HSync : out std_logic; + O_HSync : out std_logic; --@ Vertical Sync signal; **Active low** - O_VSync : out std_logic + O_VSync : out std_logic --@ @end ); end entity VGATimingGenerator_pb; @@ -45,8 +34,8 @@ begin begin if rising_edge(I_CLK) then -- General Interace - R_CE <= I_CE; - R_RST <= I_RST; + R_CE <= I_CE; + R_RST <= I_RST; -- Output Interface O_PixelReady <= C_PixelReady; @@ -56,8 +45,7 @@ begin end process; VGATimingGenerator : entity work.VGATimingGenerator - port map - ( + port map( I_CLK => I_CLK, I_CE => R_CE, I_RST => R_RST, @@ -65,4 +53,4 @@ begin O_HSync => R_HSync, O_VSync => R_VSync ); -end architecture RTL; \ No newline at end of file +end architecture RTL; diff --git a/src/VGATimingGenerator_test.vhd b/src/VGATimingGenerator_test.vhd index e80ceda..4fbdfae 100644 --- a/src/VGATimingGenerator_test.vhd +++ b/src/VGATimingGenerator_test.vhd @@ -2,124 +2,122 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; -library UNISIM; -use UNISIM.vcomponents.all; entity VGATimingGenerator_test is port ( --@ Clock signal; **Rising edge** triggered - I_CLK : in std_logic; + I_CLK : in std_logic; --@ @virtualbus VGA-Signals @dir out VGA signals --@ Horizontal Sync signal; **Active low** O_HSync : out std_logic; --@ Vertical Sync signal; **Active low** O_VSync : out std_logic; --@ VGA Red Channel - O_Red : out std_logic_vector(2 downto 0); + O_Red : out std_logic_vector(2 downto 0); --@ VGA Green Channel O_Green : out std_logic_vector(2 downto 0); --@ VGA Blue Channel - O_Blue : out std_logic_vector(1 downto 0) - --@ @end - ); + O_Blue : out std_logic_vector(1 downto 0) + --@ @end + ); end entity VGATimingGenerator_test; architecture RTL of VGATimingGenerator_test is - signal R_PixelReady : std_logic_vector(1 downto 0); + signal I_VGA_PixelCE : std_logic := '0'; + signal I_VGA_PixelRST : std_logic := '1'; - signal R_LineCounter : unsigned(19 downto 0) := (others => '0'); + signal O_VGA_Req_Y_Valid : std_logic; + signal I_VGA_Req_Y_Ready : std_logic; + signal O_VGA_Req_Y : std_logic_vector(9 downto 0); - signal R_VSync : std_logic; + signal O_VGA_Req_X_Valid : std_logic; + signal I_VGA_Req_X_Ready : std_logic; + signal O_VGA_Req_X : std_logic_vector(9 downto 0); - signal CLK_FB : std_logic; - signal PixelCLK : std_logic; + + 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 COLOR_RED : std_logic_vector(7 downto 0) := "11100000"; -- R=7, G=0, B=0 + constant COLOR_GREEN : std_logic_vector(7 downto 0) := "00011100"; -- R=0, G=7, B=0 + constant COLOR_BLUE : std_logic_vector(7 downto 0) := "00000011"; -- R=0, G=0, B=3 + + signal R_CurrentColor : std_logic_vector(7 downto 0) := COLOR_BLUE; -- Pre-Startfarbe: Blau + constant COLOR_CHANGE_INTERVAL : integer := 16; + +-- Farbwechsel-Logik (einfache zyklische Farben) + function next_color(current : std_logic_vector(7 downto 0)) return std_logic_vector is + begin + if current = COLOR_RED then -- Rot + return COLOR_GREEN; -- Grün + elsif current = COLOR_GREEN then -- Grün + return COLOR_BLUE; -- Blau + else + return COLOR_RED; -- Rot + end if; + end function; begin - ClockManager : DCM_SP - generic map( - CLKDV_DIVIDE => 2.0, - CLKFX_DIVIDE => 10, - CLKFX_MULTIPLY => 30, - CLKIN_DIVIDE_BY_2 => FALSE, - CLKIN_PERIOD => 10.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 => CLK_FB, - CLKDV => PixelCLK, - CLKFB => CLK_FB, - CLKIN => I_CLK - ); - - VGAColorGenerator : process (PixelCLK) - variable R_SignalCounter : unsigned(3 downto 0) := (others => '0'); + process (I_CLK) begin - if rising_edge(PixelCLK) then - if R_VSync = '0' then - --R_LineCounter <= (others => '0'); - --R_SignalCounter <= (others => '0'); - --O_Red <= "000"; - --O_Green <= "000"; - --O_Blue <= "00"; - else - R_PixelReady(1) <= R_PixelReady(0); - - if R_PixelReady = "10" then - R_LineCounter <= R_LineCounter + 1; - end if; - - if R_PixelReady(0) = '1' then - if R_LineCounter = 10 then - R_LineCounter <= (others => '0'); - - if R_SignalCounter = 2 then - R_SignalCounter := (others => '0'); - else - R_SignalCounter := R_SignalCounter + 1; - end if; - end if; - - if R_SignalCounter = 0 then - O_Red <= "111"; - O_Green <= "000"; - O_Blue <= "00"; - elsif R_SignalCounter = 1 then - O_Red <= "000"; - O_Green <= "111"; - O_Blue <= "00"; - elsif R_SignalCounter = 2 then - O_Red <= "000"; - O_Green <= "000"; - O_Blue <= "11"; - end if; - else - O_Red <= "000"; - O_Green <= "000"; - O_Blue <= "00"; - end if; - end if; + if rising_edge(I_CLK) then + I_VGA_PixelCE <= not I_VGA_PixelCE; end if; end process; - VGATimingGenerator : entity work.VGATimingGenerator - port map - ( - I_CLK => PixelCLK, - I_CE => '1', - I_RST => '0', - O_PixelReady => R_PixelReady(0), - O_HSync => O_HSync, - O_VSync => R_VSync - ); + I_VGA_PixelData_Valid <= O_VGA_Req_X_Valid; + I_VGA_Req_X_Ready <= O_VGA_PixelData_Ready; + process(I_CLK) + begin + if rising_edge(I_CLK) then + I_VGA_PixelRST <= '0'; - O_VSync <= R_VSync; + I_VGA_PixelData <= R_CurrentColor; -end architecture RTL; \ No newline at end of file + -- Default + I_VGA_Req_Y_Ready <= '0'; + + -- Zeilenwechsel erkennen (Req_X zurück auf 0) + if O_VGA_Req_Y_Valid = '1' and I_VGA_Req_Y_Ready = '0' then + I_VGA_Req_Y_Ready <= '1'; + + if (unsigned(O_VGA_Req_Y) mod COLOR_CHANGE_INTERVAL) = 0 then + R_CurrentColor <= next_color(R_CurrentColor); + end if; + end if; + + end if; + end process; + + INST_VGA : entity work.VGA + port map( + I_VGA_PixelCLK => I_CLK, + I_VGA_PixelCE => I_VGA_PixelCE, + I_VGA_PixelRST => I_VGA_PixelRST, + O_VGA_HSync => O_HSync, + O_VGA_VSync => O_VSync, + O_VGA_Red => O_Red, + O_VGA_Green => O_Green, + O_VGA_Blue => O_Blue, + I_VGA_CLK => I_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 + ); + + + +end architecture RTL;