Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Vga controller questions

Status
Not open for further replies.

DrStrangelove13

Programmer
Jun 20, 2004
7
US
hello,

I am trying to port the vga controller below to a 128k Ram[16:0] and was hoping someone may have already done this or could direct me towards the right way to do this. When I am having little success getting the controller to read a picture stored in the RAM correctly.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity vgacore is
port
(
reset: in std_logic; -- reset
clock: in std_logic; -- VGA dot clock
hsyncb: buffer std_logic; -- horizontal (line) sync
vsyncb: out std_logic; -- vertical (frame) sync
rgb: out std_logic_vector(5 downto 0); -- red,green,blue colors
addr: out std_logic_vector(14 downto 0); -- address into video RAM
data: in std_logic_vector(7 downto 0); -- data from video RAM
csb: out std_logic; -- video RAM chip enable
oeb: out std_logic; -- video RAM output enable
web: out std_logic -- video RAM write enable
);
end vgacore;

architecture vgacore_arch of vgacore is
signal hcnt: std_logic_vector(8 downto 0); -- horizontal pixel counter
signal vcnt: std_logic_vector(9 downto 0); -- vertical line counter
signal pixrg: std_logic_vector(7 downto 0); -- byte-wide register for 4 pixels
signal blank: std_logic; -- video blanking signal
signal pblank: std_logic; -- pipelined video blanking signal
begin

A: process(clock,reset)
begin
-- reset asynchronously clears pixel counter
if reset='1' then
hcnt <= "000000000";
-- horiz. pixel counter increments on rising edge of dot clock
elsif (clock'event and clock='1') then
-- horiz. pixel counter rolls-over after 381 pixels
if hcnt<380 then
hcnt <= hcnt + 1;
else
hcnt <= "000000000";
end if;
end if;
end process;

B: process(hsyncb,reset)
begin
-- reset asynchronously clears line counter
if reset='1' then
vcnt <= "0000000000";
-- vert. line counter increments after every horiz. line
elsif (hsyncb'event and hsyncb='1') then
-- vert. line counter rolls-over after 528 lines
if vcnt<527 then
vcnt <= vcnt + 1;
else
vcnt <= "0000000000";
end if;
end if;
end process;

C: process(clock,reset)
begin
-- reset asynchronously sets horizontal sync to inactive
if reset='1' then
hsyncb <= '1';
-- horizontal sync is recomputed on the rising edge of every dot clock
elsif (clock'event and clock='1') then
-- horiz. sync is low in this interval to signal start of a new line
if (hcnt>=291 and hcnt<337) then
hsyncb <= '0';
else
hsyncb <= '1';
end if;
end if;
end process;

D: process(hsyncb,reset)
begin
-- reset asynchronously sets vertical sync to inactive
if reset='1' then
vsyncb <= '1';
-- vertical sync is recomputed at the end of every line of pixels
elsif (hsyncb'event and hsyncb='1') then
-- vert. sync is low in this interval to signal start of a new frame
if (vcnt>=490 and vcnt<492) then
vsyncb <= '0';
else
vsyncb <= '1';
end if;
end if;
end process;

-- blank video outside of visible region: (0,0) -> (255,479)
E: blank <= '1' when (hcnt>=256 or vcnt>=480) else '0';
-- store the blanking signal for use in the next pipeline stage
F: process(clock,reset)
begin
if reset='1' then
pblank <= '0';
elsif (clock'event and clock='1') then
pblank <= blank;
end if;
end process;

-- video RAM control signals
G:
csb <= '0'; -- enable the RAM
web <= '1'; -- disable writing to the RAM
oeb <= blank; -- enable the RAM outputs when video is not blanked

-- The video RAM address is built from the lower 9 bits of the vertical
-- line counter and bits 7-2 of the horizontal pixel counter.
-- Each byte of the RAM contains four 2-bit pixels. As an example,
-- the byte at address ^h1234=^b0001,0010,0011,0100 contains the pixels
-- at (row,col) of (^h048,^hD0),(^h048,^hD1),(^h048,^hD2),(^h048,^hD3).
H: addr <= vcnt(8 downto 0) & hcnt(7 downto 2);

I: process(clock,reset)
begin
-- clear the pixel register on reset
if reset='1' then
pixrg <= "00000000";
-- pixel clock controls changes in pixel register
elsif (clock'event and clock='1') then
-- the pixel register is loaded with the contents of the video
-- RAM location when the lower two bits of the horiz. counter
-- are both zero. The active pixel is in the lower two bits
-- of the pixel register. For the next 3 clocks, the pixel
-- register is right-shifted by two bits to bring the other
-- pixels in the register into the active position.
if hcnt(1 downto 0)="00" then
pixrg <= data; -- load 4 pixels from RAM
else
pixrg <= "00" & pixrg(7 downto 2); -- right-shift pixel register
end if;
end if;
end process;

-- the color mapper translates each 2-bit pixel into a 6-bit
-- color value. When the video signal is blanked, the color
-- is forced to zero (black).
J: process(clock,reset)
begin
-- blank the video on reset
if reset='1' then
rgb <= "000000";
-- update the color outputs on every dot clock
elsif (clock'event and clock='1') then
-- map the pixel to a color if the video is not blanked
if pblank='0' then
case pixrg(1 downto 0) is
when "00" => rgb <= "110000"; -- red
when "01" => rgb <= "001100"; -- green
when "10" => rgb <= "000011"; -- blue
when others => rgb <= "111111"; -- white
end case;
-- otherwise, output black if the video is blanked
else
rgb <= "000000"; -- black
end if;
end if;
end process;

end vgacore_arch;
 
Nice code. Well laid out, nice comments.

Nothing seems obviously wrong. what is happening with your ram read?

The most likely problem is that your counts and reads etc don't line up. If you are new at this its often easy to screw up the functional timing because you forget about the clock delay that it takes before the signal actually becomes what you set it too.

Some more info about what is happening might help pinpoint it.

--
 
The main problem is that I am using a 128K RAM on my board and the code was written for a 32K Ram. Now one would think that it would be as easy as changing the ADDR from [14:0] to [16:0] and then also changin how the address is obtained from Hcnt and Vcnt but none of this works.

What happens with the code as it stands now is that the monitor light goes green(indicating sync) but no image is displayed from the .hex file I upload into RAM. I also am not sure if my logic is correct when porting this from 32k Ram (as it stands now) to 128K RAM. What I am going to try tonight is to rework all the numbers for a 25Mhz clock and 640x480 signal. This really should not fix anything but its worth a shot.

Any suggestions you may have would be greatly appreciated, especiallyin the area of the Address issue.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top