khaledismail

Members
  • Content Count

    2
  • Joined

  • Last visited

Posts posted by khaledismail


  1. Thank you very much @D@n ! Your website is rich with guidelines and tips.

    Following your advice, I changed the way I divide my clock. I used a PLL from the Vivado (Clocking Wizard) to generate 25 MHz clock from 100 MHZ clock. Before doing that, I had performed test bench for my top module, but all output signals were appearing to be (undefined). Using the PLL, The test bench runs fine now!

    I found out what where the problem was. I was resetting the BRAM address at a wrong point in the code. Which lead to a repeated display of the first row of the image only. Now the image appears like this:

    513932862_Displayedimage.thumb.jpg.99fdb410dd886ba62499dc55e009dec4.jpg

    As seen, it's close to the original image but skewed for some reason. So far I am very happy with the result and hopefully will try to know the reason of such skew.


  2. Hi everyone,

    I am trying to display image pixels stored in block RAM .coe file though VGA on the board BASYS 3.

    Description of what I have done so far, Passed this image to MATLAB to create a .coe file:

    Kaleidoscope_300_300.jpg.4e9df6d645c9473cfc976594eb41523e.jpg

    The image is a 300*300 pixels. The .coe file stores each pixel RGB data scanning from left to right horizontally then moves to the second row, imitating how the VGA code scans the screen. So the .coe file is 300 pixel* 300 pixel=90000 lines long where each line is 12 bits, Red=4 bits followed by Green=4 bits followed by Blue=4 bits.

     

    This is a VHDL code to display the image. summary of code functionality: Divide main 100 MHz clock by four to get 25 MHz clock (required pixel frequency) , establish VGA synchronization and display the image on a 640 x 480 resolution @ 60 Hz. The code is shown below:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    use IEEE.NUMERIC_STD.ALL;
    
    entity vga_driver is
        Port ( clk : in  STD_LOGIC; --100 MHz main clock.
               Hsync : out  STD_LOGIC;
               Vsync : out  STD_LOGIC;
               R,G,B : out  STD_LOGIC_VECTOR (3 downto 0));
    end vga_driver;
    
    architecture Behavioral of vga_driver is
    
    signal DFlipFlopOut1: STD_LOGIC;
    signal DFlipFlopOut1_NOT: STD_LOGIC;
    signal ClockDiv4: STD_LOGIC; -- 25 MHz Clock
    signal ClockDiv4_NOT: STD_LOGIC;
    
    constant picture_size : Integer:=90000; -- 300 Pixels* 300 Pixels picture= 90000 Pixels
    
    --Signals for Block RAM
    signal wea : STD_LOGIC_VECTOR(0 DOWNTO 0):="0";
    signal addra : STD_LOGIC_VECTOR(16 DOWNTO 0):=(others=>'0');
    signal dina : STD_LOGIC_VECTOR(11 DOWNTO 0):=(others=>'0');
    signal douta : STD_LOGIC_VECTOR(11 DOWNTO 0):=(others=>'0');
    
    	
    	constant HD : integer := 639;  --  639   Horizontal Display (640)
    	constant HFP : integer := 16;         --   16   Right border (front porch)
    	constant HSP : integer := 96;       --   96   Sync pulse (Retrace)
    	constant HBP : integer := 48;        --   48   Left boarder (back porch)
    	
    	constant VD : integer := 479;   --  479   Vertical Display (480)
    	constant VFP : integer := 10;       	 --   10   Right border (front porch)
    	constant VSP : integer := 2;				 --    2   Sync pulse (Retrace)
    	constant VBP : integer := 33;       --   33   Left boarder (back porch)
    	
    	signal hPos : integer := 0;
    	signal vPos : integer := 0;
    	
    	signal videoOn : std_logic := '0';
    	
    	component RisingEdge_DFlipFlop is
    	   port(
           Q : out std_logic;    
           Clk :in std_logic;   
           D :in  std_logic    
        );
    	end component ;
    
    component Picture_Block_RAM is
      PORT (
      clka : IN STD_LOGIC;
      wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
      addra : IN STD_LOGIC_VECTOR(16 DOWNTO 0);
      dina : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
      douta : OUT STD_LOGIC_VECTOR(11 DOWNTO 0)
    );
    end component;
    
    begin
    
    DFlipFlopOut1_NOT<=not DFlipFlopOut1;
    ClockDiv4_NOT<= not ClockDiv4;
    
    --Pass Main 100 MHz clock to 2 cascaded DFlipFLops to divide frequency by 4. Result frequency= 25 MHz.
    U1: RisingEdge_DFlipFlop Port map (clk=> clk, D=> DFlipFlopOut1_NOT, Q=>DFlipFlopOut1);
    U2: RisingEdge_DFlipFlop Port map (clk=> DFlipFlopOut1, D=> ClockDiv4_NOT, Q=>ClockDiv4);
    
    --Block RAM containing picture
    U3: Picture_Block_RAM Port map (clka=>ClockDiv4, wea=>wea, addra=>addra, dina=>dina, douta=>douta);
    
    Horizontal_position_counter:process(ClockDiv4)
    begin
    
    	if(ClockDiv4'event and ClockDiv4 = '1')then
    		if (hPos = (HD + HFP + HSP + HBP)) then
    			hPos <= 0;
    		else
    			hPos <= hPos + 1;
    		end if;
    	end if;
    end process;
    
    Vertical_position_counter:process(ClockDiv4, hPos)
    begin
    
    	if(ClockDiv4'event and ClockDiv4 = '1')then
    		if(hPos = (HD + HFP + HSP + HBP))then
    			if (vPos = (VD + VFP + VSP + VBP)) then
    				vPos <= 0;
    			else
    				vPos <= vPos + 1;
    			end if;
    		end if;
    	end if;
    end process;
    
    Horizontal_Synchronisation:process(ClockDiv4, hPos)
    begin
    
    	if(ClockDiv4'event and ClockDiv4 = '1')then
    		if((hPos <= (HD + HFP)) OR (hPos > HD + HFP + HSP))then
    			HSYNC <= '1';
    		else
    			HSYNC <= '0';
    		end if;
    	end if;
    end process;
    
    Vertical_Synchronisation:process(ClockDiv4, vPos)
    begin
    
    	if(ClockDiv4'event and ClockDiv4 = '1')then
    		if((vPos <= (VD + VFP)) OR (vPos > VD + VFP + VSP))then
    			VSYNC <= '1';
    		else
    			VSYNC <= '0';
    		end if;
    	end if;
    end process;
    
    video_on:process(ClockDiv4, hPos, vPos)
    begin
    
    	if(ClockDiv4'event and ClockDiv4 = '1')then
    		if(hPos <= HD and vPos <= VD)then
    			videoOn <= '1';
    		else
    			videoOn <= '0';
    		end if;
    	end if;
    end process;
    
    
    draw:process(ClockDiv4, hPos, vPos, videoOn)
    begin
    
    	if(ClockDiv4'event and ClockDiv4 = '1')then
    		if(videoOn = '1')then
                if (unsigned(addra)<picture_size) then
                    R<=douta(11 downto 8); G<=douta(7 downto 4); B<=douta(3 downto 0);
                    addra<=STD_LOGIC_VECTOR(unsigned(addra)+1);
    			else
    				R<=(others=>'0');G<=(others=>'0');B<=(others=>'0');
    			end if;
    		else
    			R<=(others=>'0');G<=(others=>'0');B<=(others=>'0');
    			addra<=(others=>'0');
    		end if;
    	end if;
    end process;
    
    
    end Behavioral;
    

    My problem is that the image does not display as expected. I get this displayed on my screen:

    Faulty_image.thumb.jpg.feef6a02e13ef52241236db63ea4d596.jpg

    As you see, there are 2 problems immediately noticed.

    1st: The image is not the same, obviously.

    2nd: The image should not take the whole display since it is 300 * 300 pixels while the resolution is 640*480 pixels meaning that some data is being repeated without intention. 

    The default display of BASYS 3 is this. I am putting this just for reference so you can know how my screen displays 640*480 resolution:

    BASYS3_default_dispaly.thumb.jpg.edbefbd08fff0697e6669d9e441ee09e.jpg

    I tested the VHDL code by printing colors on my screen by direct output assignment and it works as intended. So the problem is probably with accessing the block RAM.

    A snippet from my .coe file:

    MEMORY_INITIALIZATION_RADIX=2;
    MEMORY_INITIALIZATION_VECTOR=
    011101010100,
    010101110111,
    000110011111,
    010110101100,
    000110111111,
    001000100010,
    001000100010,
    001000100010,
    001000100011,
    000101100100,
    100110100001,
    111011010110,
    111110110110,
    111110000101,
    111110010100,
    :
    :
    --it goes on and on until last line, line number 90002, 90000 since 300*300 pixels= 90000. The added two is due to the first 2 lines.
    :
    :
    101100100010;

    I am stuck at this point. Where could the problem be?