Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16639 Discussions

VGA - output of a graphic not stable

Altera_Forum
Honored Contributor II
1,044 Views

Hello Community, 

 

I got a problem with my current VGA project. Here a few informations about what I want to do: 

- first ten 8-bit-rows are used to display some text like variables or sth similar. --> first 80 pixel rows are reserved for the text output 

- on the other part of the screen I want to display a graphic (described in a 32x32 memory) which I can move with some pushbuttons up/down/left/right 

 

My problem is that I don't get a stable state of my graphic. The splitting of the screen and the output of the text is no problem but I'm not able to get the graphic output correctly working. 

 

My current graphic should be a simple square (just the borders) but I get rotating stripes in the size of 64x64 on my screen (the graphic should only be 32x32) 

I think with my current code I just read some of the values from the middle of my memory. But I want to read a new 32-bit-std_logic_vector every new pixel line. These 32-bit vector I want to split up to the single pixels with a counter and my pixelclock. 

 

Here is my code for the graphic (without my VGA-sync and all the files used to display the text) 

 

library ieee;use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity graphic is generic( address_width : integer := 5; data_width : integer := 32); port( clock : in std_logic; --graphic_address : in std_logic_vector(address_width-1 downto 0); pixel_column, pixel_row : in unsigned(9 downto 0); move_up, move_down : in std_logic; move_left, move_right : in std_logic; horiz_sync : in std_logic; graphic_output : out std_logic); end graphic; architecture behavior of graphic is signal clock_counter : unsigned(24 downto 0) := (others => '0'); signal clock_counter_37_9k : unsigned(24 downto 0) := (others => '0'); signal clock_10hz : std_logic; signal clock_37_9k : std_logic; signal modified_clock : std_logic; signal graphic_read_address: std_logic_vector(address_width-1 downto 0); signal horiz_position : unsigned(9 downto 0) := "0000000000"; signal vert_position : unsigned(9 downto 0) := "0001010001"; signal graphic_output_complete_row : std_logic_vector(data_width-1 downto 0); signal counter_horiz : unsigned(5 downto 0) := "000000"; signal counter_vert : unsigned(4 downto 0) := "00000"; signal pixel_column_prev : unsigned(9 downto 0) := "0000000000"; signal display_graphic_on : std_logic :='0'; component Graphic_RAM port( address : IN STD_LOGIC_VECTOR (address_width-1 DOWNTO 0); clock : IN STD_LOGIC := '1'; data : IN STD_LOGIC_VECTOR (31 DOWNTO 0); wren : IN STD_LOGIC ; q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)); end component; begin -- RAM wrapper Graphic_RAM_inst: Graphic_RAM port map( data => "00000000000000000000000000000000", clock => horiz_sync, address => std_logic_vector(graphic_read_address), wren => '0', q => graphic_output_complete_row ); -- create a 10 hz clock for changing position at this speed process(clock) begin if rising_edge(clock) then if (clock_counter < 1999999) then clock_counter <= clock_counter +1; else clock_10hz <= not clock_10hz; clock_counter <= (others => '0'); end if; end if; end process; -- process moves the object at a speed of 10 Hz process(clock_10hz) begin if rising_edge(clock_10hz) then -- vertical movement if ((move_up = '0') and (move_down = '1')) then if (vert_position > "0001010001") then -- checks if we already reached the upper border of the graphic area vert_position <= vert_position - 1; end if; elsif (move_down = '0') then if (vert_position < "1001011000") then -- checks if we already reached the lower border of the graphic area vert_position <= vert_position + 1; end if; end if; -- horizontal movement if ((move_left = '0') and (move_right = '1')) then if (horiz_position > "0000000000") then -- checks if we already reached the left border of the graphic area horiz_position <= horiz_position - 1; end if; elsif (move_right = '0') then if (horiz_position < "1100100000") then -- checks if we already reached the right border of the graphic area horiz_position <= horiz_position + 1; end if; end if; end if; end process; process(horiz_sync, clock, vert_position, pixel_row) begin if (pixel_row = vert_position) then display_graphic_on <= '1'; -- Flag to recognize when to display the graphic for the next 32 rows elsif (pixel_row = (vert_position+32)) then display_graphic_on <= '0'; end if; end process; -- vertical positioning of the graphic process(horiz_sync, clock, vert_position, pixel_row) begin if rising_edge(horiz_sync) then if ((display_graphic_on = '1') and (counter_vert < "11110")) then graphic_read_address <= std_logic_vector(counter_vert); counter_vert <= counter_vert + 1; if (counter_vert > "11110") then counter_vert <= "00000"; end if; end if; end if; end process; process (pixel_column, pixel_row, clock) begin if rising_edge(clock) then if (horiz_position <= unsigned(pixel_column) + 32) and (horiz_position + 32 >= unsigned(pixel_column)) and (vert_position <= unsigned(pixel_row) + 32) and (vert_position + 32 >= unsigned(pixel_row)) then if (counter_horiz <= "011111") then graphic_output <= graphic_output_complete_row(to_integer(counter_horiz)); counter_horiz <= counter_horiz +1; else counter_horiz <= "000000"; graphic_output <= '0'; end if; else graphic_output <= '0'; end if; end if; end process; end behavior; 

 

Hopefully somebody can help me with my problem. I tried to get this working for days now but I have no idea how to solve this... 

 

Best, 

 

orPoG 

 

here a picture of what I get on my screen currently. (It looks like if I get one single line but thats just my camera... actually there are two very thin stripes next to each other. I think that are my borders of the square if I repeat them) 

http://www.alteraforum.com/forum/attachment.php?attachmentid=12945&stc=1
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
289 Views

Dont generate a clock with logic - generate a clock enable instead. Logic clocks can cause all sorts of timing problems. Stick with the same system clock throughout with a 10Hz clock enable.

0 Kudos
Altera_Forum
Honored Contributor II
289 Views

Thanks for your hint!  

 

Unfortunately I have never worked with a clock enable and I'm not sure if this causes the problem I got. Because I just use the 10Hz clock to move the graphic on the screen to the left/right/up/down and not for synchronization or something else on the screen. I also tried to use the pixelclock instead of the 10Hz clock. I had the same problem like before but also the problem that it was impossible to control the position of my square because it moved very fast to the corners of the screen. 

 

Thanks for your help, 

orPoG
0 Kudos
Reply