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.
This commit is contained in:
2025-04-26 10:26:52 +00:00
parent 319b51bf56
commit a73f125357
13 changed files with 404 additions and 223 deletions

2
build

Submodule build updated: 54949f43c0...d1a3b7cec9

View File

@@ -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

View File

@@ -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';

View File

@@ -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');

View File

@@ -1,3 +0,0 @@
NET I_CLK LOC = B8;
NET I_CLK TNM_NET = CLOCK;
TIMESPEC TS_CLOCK = PERIOD CLOCK 30 MHz HIGH 50 %;

View File

@@ -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;

43
src/VGA_Modes_Pkg.vhd Normal file
View File

@@ -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;

View File

@@ -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";

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -9,33 +9,209 @@
<top_module name="math_real" />
<top_module name="numeric_std" />
<top_module name="std_logic_1164" />
<top_module name="vgatiminggenerator_tb" />
<top_module name="textio" />
<top_module name="vcomponents" />
<top_module name="vga_modes_pkg" />
<top_module name="vgatiminggenerator_test_tb" />
<top_module name="vital_primitives" />
<top_module name="vital_timing" />
<top_module name="vpkg" />
</top_modules>
</db_ref>
</db_ref_list>
<WVObjectSize size="6" />
<wvobject fp_name="/vgatiminggenerator_tb/VGATimingGenerator_inst/i_clk" type="logic" db_ref_id="1">
<WVObjectSize size="16" />
<wvobject fp_name="/vgatiminggenerator_test_tb/i_clk" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">i_clk</obj_property>
<obj_property name="ObjectShortName">i_clk</obj_property>
<obj_property name="label">Clock</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/s_clk_fb" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">s_clk_fb</obj_property>
<obj_property name="ObjectShortName">s_clk_fb</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/s_clk_pixel" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">s_clk_pixel</obj_property>
<obj_property name="ObjectShortName">s_clk_pixel</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/s_clk_logic" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">s_clk_logic</obj_property>
<obj_property name="ObjectShortName">s_clk_logic</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/i_vga_pixelce" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">i_vga_pixelce</obj_property>
<obj_property name="ObjectShortName">i_vga_pixelce</obj_property>
<obj_property name="label">Pixel_CE</obj_property>
</wvobject>
<wvobject fp_name="group3" type="group">
<obj_property name="label">Testbench</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/o_hsync" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_hsync</obj_property>
<obj_property name="ObjectShortName">o_hsync</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/o_vsync" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_vsync</obj_property>
<obj_property name="ObjectShortName">o_vsync</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/o_red" type="array" db_ref_id="1">
<obj_property name="ElementShortName">o_red[2:0]</obj_property>
<obj_property name="ObjectShortName">o_red[2:0]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/o_green" type="array" db_ref_id="1">
<obj_property name="ElementShortName">o_green[2:0]</obj_property>
<obj_property name="ObjectShortName">o_green[2:0]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/o_blue" type="array" db_ref_id="1">
<obj_property name="ElementShortName">o_blue[1:0]</obj_property>
<obj_property name="ObjectShortName">o_blue[1:0]</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group9" type="group">
<obj_property name="label">UUT</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/i_vga_pixelrst" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_vga_pixelrst</obj_property>
<obj_property name="ObjectShortName">i_vga_pixelrst</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/i_vga_ce" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_vga_ce</obj_property>
<obj_property name="ObjectShortName">i_vga_ce</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/i_vga_rst" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_vga_rst</obj_property>
<obj_property name="ObjectShortName">i_vga_rst</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/i_vga_pixeldata_valid" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_vga_pixeldata_valid</obj_property>
<obj_property name="ObjectShortName">i_vga_pixeldata_valid</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/o_vga_pixeldata_ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_vga_pixeldata_ready</obj_property>
<obj_property name="ObjectShortName">o_vga_pixeldata_ready</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/i_vga_pixeldata" type="array" db_ref_id="1">
<obj_property name="ElementShortName">i_vga_pixeldata[7:0]</obj_property>
<obj_property name="ObjectShortName">i_vga_pixeldata[7:0]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/r_currentcolor" type="array" db_ref_id="1">
<obj_property name="ElementShortName">r_currentcolor[7:0]</obj_property>
<obj_property name="ObjectShortName">r_currentcolor[7:0]</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group24" type="group">
<obj_property name="label">Y</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/o_vga_req_y_valid" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_vga_req_y_valid</obj_property>
<obj_property name="ObjectShortName">o_vga_req_y_valid</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/i_vga_req_y_ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_vga_req_y_ready</obj_property>
<obj_property name="ObjectShortName">i_vga_req_y_ready</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/o_vga_req_y" type="array" db_ref_id="1">
<obj_property name="ElementShortName">o_vga_req_y[9:0]</obj_property>
<obj_property name="ObjectShortName">o_vga_req_y[9:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group25" type="group">
<obj_property name="label">X</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/o_vga_req_x_valid" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_vga_req_x_valid</obj_property>
<obj_property name="ObjectShortName">o_vga_req_x_valid</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/i_vga_req_x_ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_vga_req_x_ready</obj_property>
<obj_property name="ObjectShortName">i_vga_req_x_ready</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/o_vga_req_x" type="array" db_ref_id="1">
<obj_property name="ElementShortName">o_vga_req_x[9:0]</obj_property>
<obj_property name="ObjectShortName">o_vga_req_x[9:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group37" type="group">
<obj_property name="label">Errors</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[0]" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[0]</obj_property>
<obj_property name="ObjectShortName">r_error[0]</obj_property>
<obj_property name="label">Pixel Underrun</obj_property>
</wvobject>
<wvobject fp_name="group39" type="group">
<obj_property name="label">Raw</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error" type="array" db_ref_id="1">
<obj_property name="ElementShortName">r_error[7:0]</obj_property>
<obj_property name="ObjectShortName">r_error[7:0]</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[7]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[7]</obj_property>
<obj_property name="ObjectShortName">r_error[7]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[6]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[6]</obj_property>
<obj_property name="ObjectShortName">r_error[6]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[5]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[5]</obj_property>
<obj_property name="ObjectShortName">r_error[5]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[4]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[4]</obj_property>
<obj_property name="ObjectShortName">r_error[4]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[3]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[3]</obj_property>
<obj_property name="ObjectShortName">r_error[3]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[2]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[2]</obj_property>
<obj_property name="ObjectShortName">r_error[2]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[1]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[1]</obj_property>
<obj_property name="ObjectShortName">r_error[1]</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/r_error[0]" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[0]</obj_property>
<obj_property name="ObjectShortName">r_error[0]</obj_property>
<obj_property name="label">Pixel Underrun</obj_property>
</wvobject>
</wvobject>
</wvobject>
</wvobject>
<wvobject fp_name="divider40" type="divider">
<obj_property name="label">Slow</obj_property>
<obj_property name="DisplayName">label</obj_property>
<obj_property name="BkColor">128 128 255</obj_property>
<obj_property name="TextColor">230 230 230</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/INST_TimingGenerator/i_clk" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_clk</obj_property>
<obj_property name="ObjectShortName">i_clk</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_tb/VGATimingGenerator_inst/i_ce" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_ce</obj_property>
<obj_property name="ObjectShortName">i_ce</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/INST_AsyncPixelDataFIFO/i_read_clk" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_read_clk</obj_property>
<obj_property name="ObjectShortName">i_read_clk</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_tb/i_rst" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_rst</obj_property>
<obj_property name="ObjectShortName">i_rst</obj_property>
<wvobject fp_name="divider42" type="divider">
<obj_property name="label">Fast</obj_property>
<obj_property name="DisplayName">label</obj_property>
<obj_property name="BkColor">128 128 255</obj_property>
<obj_property name="TextColor">230 230 230</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_tb/VGATimingGenerator_inst/o_pixelready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_pixelready</obj_property>
<obj_property name="ObjectShortName">o_pixelready</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/INST_XY_Generator/i_clk" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_clk</obj_property>
<obj_property name="ObjectShortName">i_clk</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_tb/VGATimingGenerator_inst/o_hsync" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_hsync</obj_property>
<obj_property name="ObjectShortName">o_hsync</obj_property>
</wvobject>
<wvobject fp_name="/vgatiminggenerator_tb/VGATimingGenerator_inst/o_vsync" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_vsync</obj_property>
<obj_property name="ObjectShortName">o_vsync</obj_property>
<wvobject fp_name="/vgatiminggenerator_test_tb/VGATimingGenerator_test_inst/INST_VGA/INST_AsyncPixelDataFIFO/i_write_clk" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_write_clk</obj_property>
<obj_property name="ObjectShortName">i_write_clk</obj_property>
</wvobject>
</wave_config>