0
\$\begingroup\$

This question already has an answer here:

I'm trying to read from ROM and display the data on VGA monitor. I have verified that the ROM is functional and it works fine. But what I get on the screen is a repeated patterns of RGB. Not that data that's in the ROM.

Here is my ROM:

------------------------------------------------------------------
 LIBRARY ieee;
 USE ieee.std_logic_1164.all;
 library work;
 ------------------------------------------------------------------
 ENTITY rom IS
PORT (clk: IN STD_LOGIC;
address: IN INTEGER RANGE 0 to 2**15;
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END rom;
------------------------------------------------------------------
ARCHITECTURE rom OF rom IS
SIGNAL reg_address: INTEGER RANGE 0 to 2**15;
TYPE memory IS ARRAY (0 TO 15) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
 CONSTANT myrom: memory := (
0=>  "00000000", -- 0
1=>    "00000000", -- 1
2=>    "00010000", -- 2    *
3=>    "00111000", -- 3   ***
4=>    "01101100", -- 4  ** **
5=>    "11000110", -- 5 **   **
6=>    "11000110", -- 6 **   **
7=>    "11111110", -- 7 *******
8=>    "11000110", -- 8 **   **
9=>    "11000110", -- 9 **   **
10=>   "11000110", -- a **   **
11=>   "11000110", -- b **   **
12=>   "00000000", -- c
13=>   "00000000", -- d
14=>   "00000000", -- e
15=>   "00000000", -- f
 OTHERS => "00000000");
 BEGIN
 --Register the address:----------
 PROCESS (clk)
 BEGIN IF (clk'EVENT AND clk='1') THEN
 reg_address <= address;
 END IF;
 END PROCESS;
--Get unregistered output:-------
 data_out <= myrom(reg_address);
 END rom;

VGA DISPLAY

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity VGA_display is
          port (
            -- Assuming 50MHz clock.If the clock is reduced then it might give the unexpected output.      
                  clock: in std_logic;

             -- The counter tells whether the correct position on the screen is reached where the data is to be displayed. 
                  hcounter: in integer range 0 to 1023;
                  vcounter: in integer range 0 to 1023;

          -- Output the colour that should appear on the screen. 
                  pixels : out std_logic_vector(7 downto 0)               
                );
end VGA_display;

architecture Behavioral of VGA_display is   
    -- Intermediate register telling the exact position on display on screen.
         signal x : integer range 0 to 1023 := 100;
         signal y : integer range 0 to 1023 := 80;
         signal addr: INTEGER RANGE 0 TO 15;
         signal pix: STD_LOGIC_VECTOR(7 DOWNTO 0);
                   -- Clock period definitions
         constant Clk_period : time := 10 ns;

begin


      rom1: entity work.rom port map(address => addr, data_out => pix, clk => clock);



 -- On every positive edge of the clock counter condition is checked,
  output1: process(clock)
              begin
                    if rising_edge (clock) then

                    -- If the counter satisfy the condition, then output the colour that should appear.
                        if (hcounter >= 1)  and (hcounter < 128) and (vcounter >= 1) and (vcounter < 128
                               ) then

                           addr <= vcounter * 128 + hcounter;

                           pixels <= pix; 

                    -- If the condition is not satisfied then the output colour will be black.
                        else 
                          pixels <= x"00";
                        end if;
              end if;
           end process;
end Behavioral;

TOP Entity

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library work;

entity VGA_sync is
    Port ( Clk : in  STD_LOGIC;
           hsync : out  STD_LOGIC;
           vsync : out  STD_LOGIC;
           Red : out  STD_LOGIC_VECTOR (2 downto 0);
           Green : out  STD_LOGIC_VECTOR (2 downto 0);
           Blue : out  STD_LOGIC_VECTOR (2 downto 1)
          );
end VGA_sync;

architecture Behavioral of VGA_sync is

     -- Intermediate register used internally
        signal clock: std_logic := '0';

      -- Internal register to store the colour required  
          signal rgb: std_logic_vector(7 downto 0);

      -- Set the resolution of the frame - 640 x 480
        signal hCount: integer range 0 to 1023 := 640;
        signal vCount: integer range 0 to 1023 := 480;

     -- Set the count from where it should start
        signal nextHCount: integer range 0 to 1023 := 641;
        signal nextVCount: integer range 0 to 1023 := 480;


begin

      -- Divide the clock from 100 MHz to 50 MHz 
        divideClock: process(Clk)
               begin
                  if rising_edge (Clk) then
                      clock <= not clock;
                   end if;
                end process;

      -- create a file which contains the code which causes something to be displayed.
     -- The clock which should be given here is 50MHz   
      VGA_display: entity work.VGA_display
        port map(
              clock =>  clock,
              hcounter  =>  nextHCount,
              vcounter => nextVCount,
              pixels  => rgb
        );      

     -- The process is carried out for every positive edge of the clock i.e, 50 MHz clock(clock).
        vgasignal: process(clock)

                        variable divide_by_2 : std_logic := '0';

                         begin               

                            -- Make sure the process begins at the correct point between sync pulses
                               if rising_edge(clock) then

                                -- Further divide down the clock from 50 MHz to 25 MHz 
                           if divide_by_2 = '1' then

                                   -- Has an entire scanline been displayed?                        
                              if(hCount = 799) then
                                 hCount <= 0;

                                            -- Has an entire frame been displayed?                      
                                    if(vCount = 524) then
                                       vCount <= 0;

                                    else
                                       vCount <= vCount + 1;                                                          
                                    end if;

                                    else
                                  hCount <= hCount + 1;
                              end if;

                                     -- Once the Hcounter has reached the end of the line we reset it to zero
                               if (nextHCount = 799) then        
                                   nextHCount <= 0;

                                    -- Once the frame has been displayed then reset the Vcounter to zero
                                       if (nextVCount = 524) then        
                                           nextVCount <= 0;                   
                                       else
                                           nextVCount <= vCount + 1;          
                                       end if;

                                         else
                                   nextHCount <= hCount + 1;            
                               end if;

                            -- Check if the Vcount is within the minimum and maximum value for the vertical sync signal                             
                               if (vCount >= 490 and vCount < 492) then
                                   vsync <= '0';
                               else
                                   vsync <= '1';
                               end if;

                            -- Check if the Hcount is within the minimum and maximum value for the horizontal sync signal                                   
                               if (hCount >= 656 and hCount < 752) then
                                   hsync <= '0';
                               else
                                   hsync <= '1';
                               end if;

                            -- If the Vcounter and Hcounter are within 640 and 480 then display the pixels.
                               if (hCount < 640 and vCount < 480) then

                                --this section of code will cause the display to be Red

                                            Red <= rgb (7 downto 5);
                                  Green <= rgb (4 downto 2);
                                  Blue <= rgb (1 downto 0);                                         

                                end if;

                                     end if;

                                 -- Set divide_by_2 to zero 
                                     divide_by_2 := not divide_by_2;

                                end if;

                            end process;                                                                        

end Behavioral;
\$\endgroup\$

marked as duplicate by Chris Stratton, dim, ThreePhaseEel, Dave Tweed Nov 25 '16 at 1:40

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

0
\$\begingroup\$

The data in your ROM is a bitmap, but you're reading it one byte at a time, and sending each byte out the pixels port, which is treating each byte as a single color.

If you want to display the bitmap, you'll need to come up with some way of breaking that byte up into bits so that you can use one bit for each pixel. You could do this with a shift register, for instance.

\$\endgroup\$
  • \$\begingroup\$ but what's the interpretation of repeated patterns ? \$\endgroup\$ – Ahmed Saleh Nov 24 '16 at 18:05
  • \$\begingroup\$ @AhmedSaleh that depends entirely on what the repeated patterns are, how are we to know, you haven't shown us. You are repeatedly sending nonsense to the screen and seeing repeated nonsense. \$\endgroup\$ – Tom Carpenter Nov 24 '16 at 18:25
  • \$\begingroup\$ @TomCarpenter you can watch it here youtube.com/watch?v=R5g62WXPtqI \$\endgroup\$ – Ahmed Saleh Nov 24 '16 at 18:28
  • \$\begingroup\$ For an external IC memory a shift register makes sense, but for an FPGA's internal memory it is usually more sensible to make the output width of the memory match the number of bits per pixel, or split the color planes into three distinct memories. \$\endgroup\$ – Chris Stratton Nov 24 '16 at 20:12
  • 1
    \$\begingroup\$ You would read the reference materials for your FPGA and learn about what its actual memories are actually capable of. Asking questions over and over while neglecting to do any study of how these things are done is just wasting everyone's time - even your own. \$\endgroup\$ – Chris Stratton Nov 24 '16 at 20:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.