• Content Count

  • Joined

  • Last visited

  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: 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: 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: 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: 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?