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?
Question
khaledismail
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:
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:
I am stuck at this point. Where could the problem be?
Link to comment
Share on other sites
5 answers to this question
Recommended Posts
Archived
This topic is now archived and is closed to further replies.