diff --git a/build b/build index 54949f4..d1a3b7c 160000 --- a/build +++ b/build @@ -1 +1 @@ -Subproject commit 54949f43c0a900256c15d5d964c6b1da95d27473 +Subproject commit d1a3b7cec979d04999fd6e4e0560281ac65ec94e diff --git a/project.cfg b/project.cfg index 1afe342..5c7a2a1 100644 --- a/project.cfg +++ b/project.cfg @@ -2,7 +2,7 @@ # Project name # @remark The name of the project is used as default name for the top module and the ucf file -PROJECT = VGATimingGenerator +PROJECT = VGA # Target device # @example xc3s1200e-4-fg320 | xc5vlx50t-1-ff1136 @@ -12,10 +12,10 @@ TARGET_PART = xc3s1200e-4-fg320 XILINX = /opt/Xilinx/14.7/ISE_DS/ISE # Optional the name of the top module (default is the project name) -TOPLEVEL = VGATimingGenerator_test +TOPLEVEL = VGA_test # Optional the path/name of the ucf file (default is the project name) -CONSTRAINTS = src/VGATimingGenerator_test.ucf +CONSTRAINTS = src/VGA_test.ucf # Optional a target to copy the bit file to (make copy) # COPY_TARGET_DIR = @@ -29,10 +29,11 @@ CONSTRAINTS = src/VGATimingGenerator_test.ucf # @example `VHDSOURCE += src/main.vhd` (add a single VHDL file per line) # VHDSOURCE += src/VGATimingGenerator_pb.vhd -VHDSOURCE += src/VGATimingGenerator_test.vhd -VHDSOURCE += src/VGATimingGenerator.vhd +VHDSOURCE += src/VGA_test.vhd +VHDSOURCE += src/Timing_Generator.vhd VHDSOURCE += src/XY_Generator.vhd VHDSOURCE += src/VGA.vhd +VHDSOURCE += src/VGA_Modes_Pkg.vhd VHDSOURCE += ../Asynchronous-FIFO-AXI-Handshake/libs/GrayCounter.vhd VHDSOURCE += ../Asynchronous-FIFO-AXI-Handshake/src/AsyncFIFO.vhd VHDSOURCE += ../Asynchronous-FIFO-AXI-Handshake/libs/Pipeline-AXI-Handshake/src/PipelineRegister.vhd diff --git a/src/VGATimingGenerator.vhd b/src/Timing_Generator.vhd similarity index 77% rename from src/VGATimingGenerator.vhd rename to src/Timing_Generator.vhd index 1be7a26..a85d968 100644 --- a/src/VGATimingGenerator.vhd +++ b/src/Timing_Generator.vhd @@ -16,25 +16,12 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; +use work.VGA_Modes_Pkg.all; -entity VGATimingGenerator is +entity Timing_Generator is generic ( - --@ Horizontal Front Porch - G_HFront : integer := 16; - --@ Horizontal Sync Pulse - G_HSync : integer := 96; - --@ Horizontal Back Porch - G_HBack : integer := 48; - --@ Horizontal Total resolution - G_HTotal : integer := 800; - --@ Vertical Front Porch - G_VFront : integer := 10; - --@ Vertical Sync Pulse - G_VSync : integer := 2; - --@ Vertical Back Porch - G_VBack : integer := 33; - --@ Vertical Total resolution - G_VTotal : integer := 525 + --@ VGA Mode (0-9) from VGA_Modes_Pkg + G_VGA_Mode : integer := 1 ); port ( --@ Clock; (**Rising edge** triggered) @@ -53,13 +40,31 @@ entity VGATimingGenerator is O_VSync : out std_logic --@ @end ); -end entity VGATimingGenerator; +end entity Timing_Generator; + +architecture RTL of Timing_Generator is + --@ Horizontal Front Porch + constant K_HFront : integer := K_VGA_Modes(G_VGA_Mode).H_Front; + --@ Horizontal Sync Pulse + constant K_HSync : integer := K_VGA_Modes(G_VGA_Mode).H_Sync; + --@ Horizontal Back Porch + constant K_HBack : integer := K_VGA_Modes(G_VGA_Mode).H_Back; + --@ Horizontal Total resolution + constant K_HTotal : integer := K_VGA_Modes(G_VGA_Mode).H_Total; + --@ Vertical Front Porch + constant K_VFront : integer := K_VGA_Modes(G_VGA_Mode).V_Front; + --@ Vertical Sync Pulse + constant K_VSync : integer := K_VGA_Modes(G_VGA_Mode).V_Sync; + --@ Vertical Back Porch + constant K_VBack : integer := K_VGA_Modes(G_VGA_Mode).V_Back; + --@ Vertical Total resolution + constant K_VTotal : integer := K_VGA_Modes(G_VGA_Mode).V_Total; + -architecture RTL of VGATimingGenerator is --@ Horizontal Counter; max value = G_HTotal - signal R_HorizontalCounter : unsigned(integer(ceil(log2(real(G_HTotal)))) - 1 downto 0) := (others => '0'); + signal R_HorizontalCounter : unsigned(K_VGA_Modes(G_VGA_Mode).X_Width - 1 downto 0) := (others => '0'); --@ Vertical Counter; max value = G_VTotal - signal R_VerticalCounter : unsigned(integer(ceil(log2(real(G_VTotal)))) - 1 downto 0) := (others => '0'); + signal R_VerticalCounter : unsigned(K_VGA_Modes(G_VGA_Mode).Y_Width - 1 downto 0) := (others => '0'); --@ Counter Enable signal for Vertical Counter signal C_VerticalCE : std_logic := '0'; @@ -84,7 +89,7 @@ begin if I_RST = '1' then R_HorizontalCounter <= (others => '0'); elsif I_CE = '1' then - if R_HorizontalCounter = G_HTotal - 1 then + if R_HorizontalCounter = K_HTotal - 1 then R_HorizontalCounter <= (others => '0'); else R_HorizontalCounter <= R_HorizontalCounter + 1; @@ -101,7 +106,7 @@ begin if I_RST = '1' then R_HSync <= (others => '1'); elsif I_CE = '1' then - if R_HorizontalCounter < G_HSync then + if R_HorizontalCounter < K_HSync then R_HSync <= R_HSync(R_HSync'high - 1 downto R_HSync'low) & '0'; else R_HSync <= R_HSync(R_HSync'high - 1 downto R_HSync'low) & '1'; @@ -113,8 +118,8 @@ begin --@ Flag generator for horizontal visible area. P_HorizontalVisible : process (R_HorizontalCounter) begin - if R_HorizontalCounter >= G_HSync + G_HBack and - R_HorizontalCounter <= G_HTotal - G_HFront - 1 then + if R_HorizontalCounter >= K_HSync + K_HBack and + R_HorizontalCounter <= K_HTotal - K_HFront - 1 then C_HorizontalVisible <= '1'; else C_HorizontalVisible <= '0'; @@ -140,7 +145,7 @@ begin if I_RST = '1' then R_VerticalCounter <= (others => '0'); elsif (I_CE and C_VerticalCE) = '1' then - if R_VerticalCounter = G_VTotal - 1 then + if R_VerticalCounter = K_VTotal - 1 then R_VerticalCounter <= (others => '0'); else R_VerticalCounter <= R_VerticalCounter + 1; @@ -156,7 +161,7 @@ begin if I_RST = '1' then R_VSync <= '1'; elsif (I_CE and C_VerticalCE) = '1' then - if R_VerticalCounter >= G_VTotal - G_VSync then + if R_VerticalCounter >= K_VTotal - K_VSync then R_VSync <= '0'; else R_VSync <= '1'; @@ -168,8 +173,8 @@ begin --@ Flag generator for vertical visible area. P_VerticalVisible : process (R_VerticalCounter) begin - if R_VerticalCounter >= G_VBack and - R_VerticalCounter <= G_VTotal - G_VFront - G_VSync - 1 then + if R_VerticalCounter >= K_VBack and + R_VerticalCounter <= K_VTotal - K_VFront - K_VSync - 1 then C_VerticalVisible <= '1'; else C_VerticalVisible <= '0'; diff --git a/src/VGA.vhd b/src/VGA.vhd index 9f1c9a8..2c25a2b 100644 --- a/src/VGA.vhd +++ b/src/VGA.vhd @@ -2,8 +2,14 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; +use work.VGA_Modes_Pkg.all; entity VGA is + generic ( + --@ VGA Mode (0-9) from VGA_Modes_Pkg + G_VGA_Mode : integer := 2; + G_PixelBuffer_Depth : integer := 16 + ); port ( --@ Pixel Clock; (**Rising edge** triggered) I_VGA_PixelCLK : in std_logic; @@ -31,10 +37,10 @@ entity VGA is --@ @virtualbus XY-Request @dir Out Request for the X and Y positions O_VGA_Req_Y_Valid : out std_logic; I_VGA_Req_Y_Ready : in std_logic; - O_VGA_Req_Y : out std_logic_vector(9 downto 0); + O_VGA_Req_Y : out std_logic_vector(K_VGA_Modes(G_VGA_Mode).Y_Width - 1 downto 0); O_VGA_Req_X_Valid : out std_logic; I_VGA_Req_X_Ready : in std_logic; - O_VGA_Req_X : out std_logic_vector(9 downto 0); + O_VGA_Req_X : out std_logic_vector(K_VGA_Modes(G_VGA_Mode).X_Width - 1 downto 0); --@ @end --@ @virtualbus Pixel-Data @dir In Calculated pixel data @@ -68,7 +74,10 @@ architecture RTL of VGA is --@ Is set if the pixel data is requested but not available in the FIFO signal C_Error_PixelUnderrun : std_logic := '0'; begin - INST_TimingGenerator : entity work.VGATimingGenerator + INST_TimingGenerator : entity work.Timing_Generator + generic map( + G_VGA_Mode => G_VGA_Mode + ) port map( I_CLK => I_VGA_PixelCLK, I_CE => I_VGA_PixelCE, @@ -90,10 +99,7 @@ begin INST_XY_Generator : entity work.XY_Generator generic map( - G_X => 640, - G_Y => 480, - G_X_Width => 10, - G_Y_Width => 10 + G_VGA_Mode => G_VGA_Mode ) port map( I_CLK => I_VGA_CLK, @@ -111,7 +117,7 @@ begin INST_AsyncPixelDataFIFO : entity work.AsyncFIFO generic map( G_Width => 8, - G_Depth => 16, + G_Depth => G_PixelBuffer_Depth, G_RamTypeFifo => "Distributed" ) port map( @@ -144,10 +150,12 @@ begin O_VGA_Red <= O_AsyncPixelDataFIFO_Data(7 downto 5); O_VGA_Green <= O_AsyncPixelDataFIFO_Data(4 downto 2); O_VGA_Blue <= O_AsyncPixelDataFIFO_Data(1 downto 0); + elsif O_TimingGenerator_PixelReady = '1' then --@ Pixel data is requested but not available in the FIFO --@ Set error flag C_Error_PixelUnderrun <= '1'; + elsif C_DisablePixelOutput = '1' then --@ Disable pixel output O_VGA_Red <= (others => '0'); diff --git a/src/VGATimingGenerator_pb.ucf b/src/VGATimingGenerator_pb.ucf deleted file mode 100644 index 606c607..0000000 --- a/src/VGATimingGenerator_pb.ucf +++ /dev/null @@ -1,3 +0,0 @@ -NET I_CLK LOC = B8; -NET I_CLK TNM_NET = CLOCK; -TIMESPEC TS_CLOCK = PERIOD CLOCK 30 MHz HIGH 50 %; \ No newline at end of file diff --git a/src/VGATimingGenerator_pb.vhd b/src/VGATimingGenerator_pb.vhd deleted file mode 100644 index e9db739..0000000 --- a/src/VGATimingGenerator_pb.vhd +++ /dev/null @@ -1,56 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use ieee.math_real.all; - -entity VGATimingGenerator_pb is - port ( - --@ Clock signal; **Rising edge** triggered - I_CLK : in std_logic; - --@ Clock Enable signal - I_CE : in std_logic; - --@ Synchronous reset signal - 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; - --@ Vertical Sync signal; **Active low** - O_VSync : out std_logic - --@ @end - ); -end entity VGATimingGenerator_pb; - -architecture RTL of VGATimingGenerator_pb is - signal R_RST : std_logic; - signal R_CE : std_logic; - signal C_PixelReady : std_logic; - signal R_HSync : std_logic; - signal R_VSync : std_logic; -begin - - BenchmarkEnvironmentFFs : process (I_CLK) - begin - if rising_edge(I_CLK) then - -- General Interace - R_CE <= I_CE; - R_RST <= I_RST; - - -- Output Interface - O_PixelReady <= C_PixelReady; - O_HSync <= R_HSync; - O_VSync <= R_VSync; - end if; - end process; - - VGATimingGenerator : entity work.VGATimingGenerator - port map( - I_CLK => I_CLK, - I_CE => R_CE, - I_RST => R_RST, - O_PixelReady => C_PixelReady, - O_HSync => R_HSync, - O_VSync => R_VSync - ); -end architecture RTL; diff --git a/src/VGA_Modes_Pkg.vhd b/src/VGA_Modes_Pkg.vhd new file mode 100644 index 0000000..9d3b2ca --- /dev/null +++ b/src/VGA_Modes_Pkg.vhd @@ -0,0 +1,43 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package VGA_Modes_Pkg is + + -- Struktur für einen Timing-Eintrag + type T_VGA_Mode is record + X_Resolution : integer; + Y_Resolution : integer; + + X_Width : integer; + Y_Width : integer; + + H_Front : integer; + H_Sync : integer; + H_Back : integer; + H_Total : integer; + + V_Front : integer; + V_Sync : integer; + V_Back : integer; + V_Total : integer; + end record; + + -- Array mit allen Modi + type T_VGA_Mode_Array is array(0 to 9) of T_VGA_Mode; + + constant K_VGA_Modes : T_VGA_Mode_Array := ( + -- X, Y, XW, YW, H_Front, H_Sync, H_Back, H_Total, V_Front, V_Sync, V_Back, V_Total + 0 => (320, 240, 9, 9, 8, 48, 24, 400, 5, 1, 16, 262), -- ~12.6 MHz + 1 => (400, 300, 10, 9, 20, 64, 44, 528, 0, 2, 12, 314), -- ~20 MHz + 2 => (640, 480, 10, 10, 16, 96, 48, 800, 10, 2, 33, 525), -- 25.175 MHz + 3 => (800, 600, 11, 10, 40, 128, 88, 1056, 1, 4, 23, 628), -- 40 MHz + 4 => (1024, 768, 11, 10, 24, 136, 160, 1344, 3, 6, 29, 806), -- 65 MHz + 5 => (1280, 720, 11, 10, 110, 40, 220, 1650, 5, 5, 20, 750), -- 74.25 MHz + 6 => (1280, 1024, 11, 11, 48, 112, 248, 1688, 1, 3, 38, 1066), -- 108 MHz + 7 => (1600, 1200, 12, 11, 64, 192, 304, 2160, 1, 3, 46, 1250), -- 162 MHz + 8 => (1920, 1080, 12, 11, 88, 44, 148, 2200, 4, 5, 36, 1125), -- 148.5 MHz + 9 => (0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) -- Reserve + ); + +end package; diff --git a/src/VGATimingGenerator_test.ucf b/src/VGA_test.ucf similarity index 75% rename from src/VGATimingGenerator_test.ucf rename to src/VGA_test.ucf index 70a8966..0830fe7 100644 --- a/src/VGATimingGenerator_test.ucf +++ b/src/VGA_test.ucf @@ -2,14 +2,16 @@ NET I_CLK LOC = B8; NET I_CLK TNM_NET = CLOCK; TIMESPEC TS_CLOCK = PERIOD CLOCK 50 MHz HIGH 50 %; -NET O_VGA_HSync LOC = T4 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; -NET O_VGA_VSync LOC = U3 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; +NET O_VGA_HSync LOC = T4 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; +NET O_VGA_VSync LOC = U3 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; -NET O_VGA_Pixel<0> LOC = R9 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; -NET O_VGA_Pixel<1> LOC = T8 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; -NET O_VGA_Pixel<2> LOC = R8 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; -NET O_VGA_Pixel<3> LOC = N8 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; -NET O_VGA_Pixel<4> LOC = P8 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; -NET O_VGA_Pixel<5> LOC = P6 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; -NET O_VGA_Pixel<6> LOC = U5 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; -NET O_VGA_Pixel<7> LOC = U4 | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; +NET O_VGA_Pixel<0> LOC = R9 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; +NET O_VGA_Pixel<1> LOC = T8 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; +NET O_VGA_Pixel<2> LOC = R8 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; +NET O_VGA_Pixel<3> LOC = N8 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; +NET O_VGA_Pixel<4> LOC = P8 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; +NET O_VGA_Pixel<5> LOC = P6 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; +NET O_VGA_Pixel<6> LOC = U5 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; +NET O_VGA_Pixel<7> LOC = U4 | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 12; + +NET "O_LED" LOC = "P4"; \ No newline at end of file diff --git a/src/VGATimingGenerator_test.vhd b/src/VGA_test.vhd similarity index 64% rename from src/VGATimingGenerator_test.vhd rename to src/VGA_test.vhd index b1f9dc2..01e8def 100644 --- a/src/VGATimingGenerator_test.vhd +++ b/src/VGA_test.vhd @@ -2,8 +2,16 @@ 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 VGATimingGenerator_test is + +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; @@ -13,29 +21,32 @@ entity VGATimingGenerator_test is --@ 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) + O_VGA_Pixel : out std_logic_vector(7 downto 0); --@ @end - + O_LED : out std_logic := '0' ); -end entity VGATimingGenerator_test; +end entity VGA_test; -architecture RTL of VGATimingGenerator_test is +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(9 downto 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(9 downto 0); + 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'; @@ -99,9 +110,36 @@ architecture RTL of VGATimingGenerator_test is 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 @@ -114,44 +152,50 @@ begin I_VGA_PixelData <= R_CurrentColor when R_MUX_Color = '0' else R_CurrentColorAlt; - process(I_CLK) + process(S_CLK) begin - if rising_edge(I_CLK) then - I_VGA_PixelRST <= '0'; + 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(640-1, O_VGA_Req_X'length) then - R_MUX_Color <= '0'; - elsif unsigned(O_VGA_Req_X) = to_unsigned(320-1, O_VGA_Req_X'length) then - R_MUX_Color <= '1'; + 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; - 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); + 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; - elsif I_VGA_Req_Y_Ready = '1' then - I_VGA_Req_Y_Ready <= '0'; + 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 => I_CLK, + 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 => I_CLK, + 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, @@ -162,9 +206,10 @@ begin 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 + I_VGA_PixelData => I_VGA_PixelData, + O_VGA_Error => R_Error ); - + O_LED <= R_Error(0); end architecture RTL; diff --git a/src/XY_Generator.vhd b/src/XY_Generator.vhd index 46b8e2a..491ec08 100644 --- a/src/XY_Generator.vhd +++ b/src/XY_Generator.vhd @@ -2,15 +2,12 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; +use work.VGA_Modes_Pkg.all; entity XY_Generator is generic ( - G_X : integer := 640; - G_Y : integer := 480; - --@ Width of the X position (Row) register - G_X_Width : integer := 10; - --@ Width of the Y position (Line) register - G_Y_Width : integer := 10 + --@ VGA Mode (0-9) from VGA_Modes_Pkg + G_VGA_Mode : integer := 2 ); port ( --@ Clock; (**Rising edge** triggered) @@ -23,12 +20,12 @@ entity XY_Generator is --@ @virtualbus Y @dir Out Output of the Y positions, with priority over X O_Y_Valid : out std_logic; I_Y_Ready : in std_logic; - O_Y : out std_logic_vector(G_Y_Width - 1 downto 0); + O_Y : out std_logic_vector(K_VGA_Modes(G_VGA_Mode).Y_Width - 1 downto 0); --@ @end --@ @virtualbus Y @dir Out Output of the X positions O_X_Valid : out std_logic; I_X_Ready : in std_logic; - O_X : out std_logic_vector(G_X_Width - 1 downto 0) + O_X : out std_logic_vector(K_VGA_Modes(G_VGA_Mode).X_Width - 1 downto 0) --@ @end ); @@ -36,8 +33,12 @@ entity XY_Generator is end entity XY_Generator; architecture RTL of XY_Generator is - signal R_X_Counter : unsigned(G_X_Width - 1 downto 0) := (others => '0'); - signal R_Y_Counter : unsigned(G_Y_Width - 1 downto 0) := (others => '0'); + + constant K_X : integer := K_VGA_Modes(G_VGA_Mode).X_Resolution; + constant K_Y : integer := K_VGA_Modes(G_VGA_Mode).Y_Resolution; + + signal R_X_Counter : unsigned(K_VGA_Modes(G_VGA_Mode).X_Width - 1 downto 0) := (others => '0'); + signal R_Y_Counter : unsigned(K_VGA_Modes(G_VGA_Mode).Y_Width - 1 downto 0) := (others => '0'); signal R_Y_Valid : std_logic := '1'; signal R_X_Valid : std_logic := '1'; @@ -64,11 +65,11 @@ begin R_X_Valid <= '0'; end if; else - if R_X_Counter = (G_X - 1) then + if R_X_Counter = (K_X - 1) then R_X_Counter <= (others => '0'); R_X_Valid <= '1'; - if R_Y_Counter = (G_Y - 1) then + if R_Y_Counter = (K_Y - 1) then R_Y_Counter <= (others => '0'); R_Y_Valid <= '1'; else diff --git a/tests/VGATimingGenerator_tb.vhd b/tests/VGATimingGenerator_tb.vhd deleted file mode 100644 index edc7927..0000000 --- a/tests/VGATimingGenerator_tb.vhd +++ /dev/null @@ -1,45 +0,0 @@ - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity VGATimingGenerator_tb is -end; - -architecture bench of VGATimingGenerator_tb is - -- Clock period - constant clk_period : time := 40 ns; - -- Ports - signal I_CLK : std_logic := '0'; - signal I_CE : std_logic := '1'; - signal I_RST : std_logic := '1'; - signal O_PixelReady : std_logic; - signal O_HSync : std_logic; - signal O_VSync : std_logic; -begin - - VGATimingGenerator_inst : entity work.VGATimingGenerator - port map - ( - I_CLK => I_CLK, - I_CE => I_CE, - I_RST => I_RST, - O_PixelReady => O_PixelReady, - O_HSync => O_HSync, - O_VSync => O_VSync - ); - - I_CLK <= not I_CLK after clk_period/2; - - process - begin - wait for 100 ms; - I_RST <= '0'; - wait for 500 ms; - I_RST <= '1'; - wait for 100 ms; - I_RST <= '0'; - wait; - end process; - -end; \ No newline at end of file diff --git a/tests/VGATimingGenerator_test_tb.vhd b/tests/VGATimingGenerator_test_tb.vhd index e49e49b..5843f53 100644 --- a/tests/VGATimingGenerator_test_tb.vhd +++ b/tests/VGATimingGenerator_test_tb.vhd @@ -17,17 +17,21 @@ architecture bench of VGATimingGenerator_test_tb is signal O_Red : std_logic_vector(2 downto 0); signal O_Green : std_logic_vector(2 downto 0); signal O_Blue : std_logic_vector(1 downto 0); + signal O_Pixel : std_logic_vector(7 downto 0); begin - VGATimingGenerator_test_inst : entity work.VGATimingGenerator_test + VGATimingGenerator_test_inst : entity work.VGA_test port map ( I_CLK => I_CLK, O_VGA_HSync => O_HSync, O_VGA_VSync => O_VSync, - O_Red => O_Red, - O_Green => O_Green, - O_Blue => O_Blue + O_VGA_Pixel => O_Pixel ); + + O_Red <= O_Pixel(2 downto 0); + O_Green <= O_Pixel(5 downto 3); + O_Blue <= O_Pixel(7 downto 6); + I_CLK <= not I_CLK after clk_period/2; end; diff --git a/tests/default.wcfg b/tests/default.wcfg index 9ea8e2c..34d5ae1 100644 --- a/tests/default.wcfg +++ b/tests/default.wcfg @@ -9,33 +9,209 @@ - + + + + + + + - - + + + label + i_clk + i_clk + Clock + + + s_clk_fb + s_clk_fb + + + s_clk_pixel + s_clk_pixel + + + s_clk_logic + s_clk_logic + + + label + i_vga_pixelce + i_vga_pixelce + Pixel_CE + + + Testbench + label + + o_hsync + o_hsync + + + o_vsync + o_vsync + + + o_red[2:0] + o_red[2:0] + + + o_green[2:0] + o_green[2:0] + + + o_blue[1:0] + o_blue[1:0] + + + + UUT + label + + i_vga_pixelrst + i_vga_pixelrst + + + i_vga_ce + i_vga_ce + + + i_vga_rst + i_vga_rst + + + i_vga_pixeldata_valid + i_vga_pixeldata_valid + + + o_vga_pixeldata_ready + o_vga_pixeldata_ready + + + i_vga_pixeldata[7:0] + i_vga_pixeldata[7:0] + + + r_currentcolor[7:0] + r_currentcolor[7:0] + + + + Y + label + + o_vga_req_y_valid + o_vga_req_y_valid + + + i_vga_req_y_ready + i_vga_req_y_ready + + + o_vga_req_y[9:0] + o_vga_req_y[9:0] + UNSIGNEDDECRADIX + + + + X + label + + o_vga_req_x_valid + o_vga_req_x_valid + + + i_vga_req_x_ready + i_vga_req_x_ready + + + o_vga_req_x[9:0] + o_vga_req_x[9:0] + UNSIGNEDDECRADIX + + + + Errors + label + + label + [0] + r_error[0] + Pixel Underrun + + + Raw + label + + r_error[7:0] + r_error[7:0] + + [7] + r_error[7] + + + [6] + r_error[6] + + + [5] + r_error[5] + + + [4] + r_error[4] + + + [3] + r_error[3] + + + [2] + r_error[2] + + + [1] + r_error[1] + + + label + [0] + r_error[0] + Pixel Underrun + + + + + + Slow + label + 128 128 255 + 230 230 230 + + i_clk i_clk - - i_ce - i_ce + + i_read_clk + i_read_clk - - i_rst - i_rst + + Fast + label + 128 128 255 + 230 230 230 - - o_pixelready - o_pixelready + + i_clk + i_clk - - o_hsync - o_hsync - - - o_vsync - o_vsync + + i_write_clk + i_write_clk